summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/io.pri6
-rw-r--r--src/corelib/io/qdatastream.cpp3
-rw-r--r--src/corelib/io/qdatastream.h5
-rw-r--r--src/corelib/io/qdebug.h32
-rw-r--r--src/corelib/io/qdir.cpp2
-rw-r--r--src/corelib/io/qdiriterator.cpp2
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp192
-rw-r--r--src/corelib/io/qfilesystementry.cpp6
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp4
-rw-r--r--src/corelib/io/qfilesystemiterator_win.cpp14
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h6
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp6
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp15
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp73
-rw-r--r--src/corelib/io/qlockfile_win.cpp14
-rw-r--r--src/corelib/io/qprocess.cpp12
-rw-r--r--src/corelib/io/qprocess_unix.cpp100
-rw-r--r--src/corelib/io/qprocess_win.cpp2
-rw-r--r--src/corelib/io/qresource.cpp24
-rw-r--r--src/corelib/io/qsettings.cpp87
-rw-r--r--src/corelib/io/qsettings.h2
-rw-r--r--src/corelib/io/qstandardpaths.cpp203
-rw-r--r--src/corelib/io/qstandardpaths_blackberry.cpp9
-rw-r--r--src/corelib/io/qstandardpaths_mac.cpp25
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp28
-rw-r--r--src/corelib/io/qstandardpaths_winrt.cpp127
-rw-r--r--src/corelib/io/qtemporaryfile.cpp17
-rw-r--r--src/corelib/io/qurlidna.cpp2
-rw-r--r--src/corelib/io/qurlrecode.cpp186
-rw-r--r--src/corelib/io/qwindowspipereader.cpp3
-rw-r--r--src/corelib/io/qwindowspipereader_p.h2
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp4
-rw-r--r--src/corelib/io/qwinoverlappedionotifier.cpp139
-rw-r--r--src/corelib/io/qwinoverlappedionotifier_p.h47
34 files changed, 1002 insertions, 397 deletions
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 649493f8b7..3f2f025aeb 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -94,7 +94,6 @@ SOURCES += \
io/qloggingregistry.cpp
win32 {
- SOURCES += io/qsettings_win.cpp
SOURCES += io/qfsfileengine_win.cpp
SOURCES += io/qlockfile_win.cpp
@@ -102,11 +101,12 @@ win32 {
HEADERS += io/qfilesystemwatcher_win_p.h
SOURCES += io/qfilesystemengine_win.cpp
SOURCES += io/qfilesystemiterator_win.cpp
- SOURCES += io/qstandardpaths_win.cpp
!winrt {
+ SOURCES += io/qsettings_win.cpp
HEADERS += io/qwindowspipewriter_p.h
SOURCES += io/qwindowspipewriter.cpp
+ SOURCES += io/qstandardpaths_win.cpp
wince* {
SOURCES += io/qprocess_wince.cpp
@@ -119,6 +119,8 @@ win32 {
io/qwinoverlappedionotifier.cpp \
io/qwindowspipereader.cpp
}
+ } else {
+ SOURCES += io/qstandardpaths_winrt.cpp
}
} else:unix|integrity {
SOURCES += \
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index af5605f8c7..a6fbffee7e 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -251,7 +251,7 @@ QT_BEGIN_NAMESPACE
return retVal;
enum {
- DefaultStreamVersion = QDataStream::Qt_5_2
+ DefaultStreamVersion = QDataStream::Qt_5_3
};
/*!
@@ -541,6 +541,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_0 Version 13 (Qt 5.0)
\value Qt_5_1 Version 14 (Qt 5.1)
\value Qt_5_2 Version 15 (Qt 5.2)
+ \value Qt_5_3 Same as Qt_5_2
\sa setVersion(), version()
*/
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index f107e801b6..28f1d51a12 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -87,8 +87,9 @@ public:
Qt_4_9 = Qt_4_8,
Qt_5_0 = 13,
Qt_5_1 = 14,
- Qt_5_2 = 15
-#if QT_VERSION >= 0x050300
+ Qt_5_2 = 15,
+ Qt_5_3 = Qt_5_2
+#if QT_VERSION >= 0x050400
#error Add the datastream version for this Qt version
#endif
};
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 9ed5f6e951..00177b659e 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -80,7 +80,9 @@ public:
inline QDebug &operator=(const QDebug &other);
inline ~QDebug() {
if (!--stream->ref) {
- if(stream->message_output) {
+ if (stream->space && stream->buffer.endsWith(QLatin1Char(' ')))
+ stream->buffer.chop(1);
+ if (stream->message_output) {
QT_TRY {
qt_message_output(stream->type,
stream->context,
@@ -172,6 +174,7 @@ template <class T>
inline QDebug operator<<(QDebug debug, const QList<T> &list)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << '(';
for (typename QList<T>::size_type i = 0; i < list.count(); ++i) {
if (i)
@@ -179,7 +182,8 @@ inline QDebug operator<<(QDebug debug, const QList<T> &list)
debug << list.at(i);
}
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
#if defined(FORCE_UREF)
@@ -190,7 +194,9 @@ template <typename T>
inline QDebug operator<<(QDebug debug, const QVector<T> &vec)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QVector";
+ debug.setAutoInsertSpaces(oldSetting);
return operator<<(debug, vec.toList());
}
@@ -202,13 +208,15 @@ template <class aKey, class aT>
inline QDebug operator<<(QDebug debug, const QMap<aKey, aT> &map)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QMap(";
for (typename QMap<aKey, aT>::const_iterator it = map.constBegin();
it != map.constEnd(); ++it) {
debug << '(' << it.key() << ", " << it.value() << ')';
}
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
#if defined(FORCE_UREF)
@@ -219,12 +227,14 @@ template <class aKey, class aT>
inline QDebug operator<<(QDebug debug, const QHash<aKey, aT> &hash)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QHash(";
for (typename QHash<aKey, aT>::const_iterator it = hash.constBegin();
it != hash.constEnd(); ++it)
debug << '(' << it.key() << ", " << it.value() << ')';
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
#if defined(FORCE_UREF)
@@ -235,14 +245,18 @@ template <class T1, class T2>
inline QDebug operator<<(QDebug debug, const QPair<T1, T2> &pair)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QPair(" << pair.first << ',' << pair.second << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
template <typename T>
inline QDebug operator<<(QDebug debug, const QSet<T> &set)
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QSet";
+ debug.setAutoInsertSpaces(oldSetting);
return operator<<(debug, set.toList());
}
@@ -254,6 +268,7 @@ template <class T>
inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QContiguousCache(";
for (int i = cache.firstIndex(); i <= cache.lastIndex(); ++i) {
debug << cache[i];
@@ -261,7 +276,8 @@ inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
debug << ", ";
}
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
#if defined(FORCE_UREF)
@@ -272,6 +288,7 @@ template <class T>
inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QFlags(";
bool needSeparator = false;
for (uint i = 0; i < sizeof(T) * 8; ++i) {
@@ -284,7 +301,8 @@ inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
}
}
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 015f4cfe14..3075e0fb12 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2144,7 +2144,7 @@ QString QDir::cleanPath(const QString &path)
name.replace(dir_separator, QLatin1Char('/'));
bool allowUncPaths = false;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) //allow unc paths
allowUncPaths = true;
#endif
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp
index 5b48c4c7db..79cdec9674 100644
--- a/src/corelib/io/qdiriterator.cpp
+++ b/src/corelib/io/qdiriterator.cpp
@@ -477,7 +477,7 @@ QDirIterator::~QDirIterator()
/*!
Advances the iterator to the next entry, and returns the file path of this
new entry. If hasNext() returns \c false, this function does nothing, and
- returns a null QString.
+ returns an empty QString.
You can call fileName() or filePath() to get the current entry file name
or path, or fileInfo() to get a QFileInfo for the current entry.
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 257f18a6bb..dbc6d28846 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -63,13 +63,28 @@
# include <types.h>
#endif
#include <objbase.h>
-#include <shlobj.h>
+#ifndef Q_OS_WINRT
+# include <shlobj.h>
+# include <accctrl.h>
+#endif
#include <initguid.h>
-#include <accctrl.h>
#include <ctype.h>
#include <limits.h>
-#define SECURITY_WIN32
-#include <security.h>
+#ifndef Q_OS_WINRT
+# define SECURITY_WIN32
+# include <security.h>
+#else // !Q_OS_WINRT
+# include <wrl.h>
+# include <windows.foundation.h>
+# include <windows.storage.h>
+# include <Windows.ApplicationModel.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::ApplicationModel;
+#endif // Q_OS_WINRT
#ifndef SPI_GETPLATFORMTYPE
#define SPI_GETPLATFORMTYPE 257
@@ -141,7 +156,7 @@ QT_BEGIN_NAMESPACE
Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0;
-#if defined(Q_OS_WINCE)
+#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
static QString qfsPrivateCurrentDir = QLatin1String("");
// As none of the functions we try to resolve do exist on Windows CE
// we use QT_NO_LIBRARY to shorten everything up a little bit.
@@ -289,14 +304,14 @@ static bool resolveUNCLibs()
}
#endif
triedResolve = true;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
HINSTANCE hLib = QSystemLibrary::load(L"Netapi32");
if (hLib) {
ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum");
if (ptrNetShareEnum)
ptrNetApiBufferFree = (PtrNetApiBufferFree)GetProcAddress(hLib, "NetApiBufferFree");
}
-#endif
+#endif // !Q_OS_WINCE && !Q_OS_WINRT
}
return ptrNetShareEnum && ptrNetApiBufferFree;
}
@@ -304,7 +319,7 @@ static bool resolveUNCLibs()
static QString readSymLink(const QFileSystemEntry &link)
{
QString result;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
HANDLE handle = CreateFile((wchar_t*)link.nativeFilePath().utf16(),
FILE_READ_EA,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
@@ -347,11 +362,11 @@ static QString readSymLink(const QFileSystemEntry &link)
result.replace(0,matchVolName.matchedLength(), QString::fromWCharArray(buffer));
}
}
-#endif
+#endif // !Q_OS_WINCE && !Q_OS_WINRT
}
#else
Q_UNUSED(link);
-#endif // Q_OS_WINCE
+#endif // Q_OS_WINCE || Q_OS_WINRT
return result;
}
@@ -432,7 +447,11 @@ static inline bool getFindData(QString path, WIN32_FIND_DATA &findData)
// can't handle drives
if (!path.endsWith(QLatin1Char(':'))) {
+#ifndef Q_OS_WINRT
HANDLE hFind = ::FindFirstFile((wchar_t*)path.utf16(), &findData);
+#else
+ HANDLE hFind = ::FindFirstFileEx((const wchar_t*)path.utf16(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0);
+#endif
if (hFind != INVALID_HANDLE_VALUE) {
::FindClose(hFind);
return true;
@@ -506,7 +525,7 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
{
// can be //server or //server/share
QString absPath;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QVarLengthArray<wchar_t, MAX_PATH> buf(qMax(MAX_PATH, path.size() + 1));
wchar_t *fileName = 0;
DWORD retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName);
@@ -516,12 +535,17 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
}
if (retLen != 0)
absPath = QString::fromWCharArray(buf.data(), retLen);
-#else
+#elif !defined(Q_OS_WINCE)
+ if (QDir::isRelativePath(path))
+ absPath = QDir::toNativeSeparators(QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + path));
+ else
+ absPath = QDir::toNativeSeparators(QDir::cleanPath(path));
+#else // Q_OS_WINRT
if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\')))
absPath = QDir::toNativeSeparators(path);
else
absPath = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path));
-#endif
+#endif // Q_OS_WINCE
// This is really ugly, but GetFullPathName strips off whitespace at the end.
// If you for instance write ". " in the lineedit of QFileDialog,
// (which is an invalid filename) this function will strip the space off and viola,
@@ -548,9 +572,17 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
ret = entry.filePath();
#endif
} else {
+#ifndef Q_OS_WINRT
ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + entry.filePath());
+#else
+ // Some WinRT APIs do not support absolute paths (due to sandboxing).
+ // Thus the port uses the executable's directory as its root directory
+ // and treats paths relative to that as absolute paths.
+ ret = QDir::cleanPath(QDir::current().relativeFilePath(entry.filePath()));
+#endif
}
+#ifndef Q_OS_WINRT
// The path should be absolute at this point.
// From the docs :
// Absolute paths begin with the directory separator "/"
@@ -563,6 +595,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
// Force uppercase drive letters.
ret[0] = ret.at(0).toUpper();
}
+#endif // !Q_OS_WINRT
return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
}
@@ -590,18 +623,24 @@ typedef struct _FILE_ID_INFO {
static inline QByteArray fileId(HANDLE handle)
{
QByteArray result;
+#ifndef Q_OS_WINRT
BY_HANDLE_FILE_INFORMATION info;
if (GetFileInformationByHandle(handle, &info)) {
result = QByteArray::number(uint(info.nFileIndexLow), 16);
result += ':';
result += QByteArray::number(uint(info.nFileIndexHigh), 16);
}
+#else // !Q_OS_WINRT
+ Q_UNUSED(handle);
+ Q_UNIMPLEMENTED();
+#endif // Q_OS_WINRT
return result;
}
// File ID for Windows starting from version 8.
QByteArray fileIdWin8(HANDLE handle)
{
+#ifndef Q_OS_WINRT
typedef BOOL (WINAPI* GetFileInformationByHandleExType)(HANDLE, Q_FILE_INFO_BY_HANDLE_CLASS, void *, DWORD);
// Dynamically resolve GetFileInformationByHandleEx (Vista onwards).
@@ -621,6 +660,16 @@ QByteArray fileIdWin8(HANDLE handle)
result += QByteArray((char *)&infoEx.FileId, sizeof(infoEx.FileId)).toHex();
}
}
+#else // !Q_OS_WINRT
+ QByteArray result;
+ FILE_ID_INFO infoEx;
+ if (GetFileInformationByHandleEx(handle, FileIdInfo,
+ &infoEx, sizeof(FILE_ID_INFO))) {
+ result = QByteArray::number(infoEx.VolumeSerialNumber, 16);
+ result += ':';
+ result += QByteArray((char *)infoEx.FileId.Identifier, sizeof(infoEx.FileId.Identifier)).toHex();
+ }
+#endif // Q_OS_WINRT
return result;
}
#endif // !Q_OS_WINCE
@@ -631,8 +680,13 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry)
#ifndef Q_OS_WINCE
QByteArray result;
const HANDLE handle =
+#ifndef Q_OS_WINRT
CreateFile((wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#else // !Q_OS_WINRT
+ CreateFile2((const wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ,
+ FILE_SHARE_READ, OPEN_EXISTING, NULL);
+#endif // Q_OS_WINRT
if (handle) {
result = QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS8 ?
fileIdWin8(handle) : fileId(handle);
@@ -810,7 +864,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa
{
bool entryExists = false;
DWORD fileAttrib = 0;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
if (fname.isDriveRoot()) {
// a valid drive ??
DWORD drivesBitmask = ::GetLogicalDrives();
@@ -851,7 +905,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa
fileAttrib = FILE_ATTRIBUTE_DIRECTORY;
entryExists = true;
}
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
}
#endif
if (entryExists)
@@ -894,12 +948,32 @@ bool QFileSystemEngine::fillMetaData(HANDLE fHandle, QFileSystemMetaData &data,
{
data.entryFlags &= ~what;
clearWinStatData(data);
+#ifndef Q_OS_WINRT
BY_HANDLE_FILE_INFORMATION fileInfo;
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
if (GetFileInformationByHandle(fHandle , &fileInfo)) {
data.fillFromFindInfo(fileInfo);
}
SetErrorMode(oldmode);
+#else // !Q_OS_WINRT
+ FILE_BASIC_INFO fileBasicInfo;
+ if (GetFileInformationByHandleEx(fHandle, FileBasicInfo, &fileBasicInfo, sizeof(fileBasicInfo))) {
+ data.fillFromFileAttribute(fileBasicInfo.FileAttributes);
+ data.creationTime_.dwHighDateTime = fileBasicInfo.CreationTime.HighPart;
+ data.creationTime_.dwLowDateTime = fileBasicInfo.CreationTime.LowPart;
+ data.lastAccessTime_.dwHighDateTime = fileBasicInfo.LastAccessTime.HighPart;
+ data.lastAccessTime_.dwLowDateTime = fileBasicInfo.LastAccessTime.LowPart;
+ data.lastWriteTime_.dwHighDateTime = fileBasicInfo.LastWriteTime.HighPart;
+ data.lastWriteTime_.dwLowDateTime = fileBasicInfo.LastWriteTime.LowPart;
+ if (!(data.fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY)) {
+ FILE_STANDARD_INFO fileStandardInfo;
+ if (GetFileInformationByHandleEx(fHandle, FileStandardInfo, &fileStandardInfo, sizeof(fileStandardInfo)))
+ data.size_ = fileStandardInfo.EndOfFile.QuadPart;
+ } else
+ data.size_ = 0;
+ data.knownFlagsMask |= QFileSystemMetaData::Times | QFileSystemMetaData::SizeAttribute;
+ }
+#endif // Q_OS_WINRT
return data.hasFlags(what);
}
@@ -931,7 +1005,9 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
}
if (what & QFileSystemMetaData::WinStatFlags) {
+#ifndef Q_OS_WINRT
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+#endif
clearWinStatData(data);
WIN32_FIND_DATA findData;
// The memory structure for WIN32_FIND_DATA is same as WIN32_FILE_ATTRIBUTE_DATA
@@ -943,11 +1019,15 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
} else {
if (!tryFindFallback(fname, data))
if (!tryDriveUNCFallback(fname, data)) {
+#ifndef Q_OS_WINRT
SetErrorMode(oldmode);
+#endif
return false;
}
}
+#ifndef Q_OS_WINRT
SetErrorMode(oldmode);
+#endif
}
if (what & QFileSystemMetaData::Permissions)
@@ -1006,7 +1086,14 @@ static bool isDirPath(const QString &dirPath, bool *existed)
if (path.length() == 2 && path.at(1) == QLatin1Char(':'))
path += QLatin1Char('\\');
+#ifndef Q_OS_WINRT
DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16());
+#else // Q_OS_WINRT
+ DWORD fileAttrib = INVALID_FILE_ATTRIBUTES;
+ WIN32_FILE_ATTRIBUTE_DATA data;
+ if (::GetFileAttributesEx((const wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), GetFileExInfoStandard, &data))
+ fileAttrib = data.dwFileAttributes;
+#endif // Q_OS_WINRT
if (fileAttrib == INVALID_FILE_ATTRIBUTES) {
int errorCode = GetLastError();
if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) {
@@ -1100,6 +1187,30 @@ QString QFileSystemEngine::rootPath()
{
#if defined(Q_OS_WINCE)
QString ret = QLatin1String("/");
+#elif defined(Q_OS_WINRT)
+ // We specify the package root as root directory
+ QString ret = QLatin1String("/");
+ // Get package location
+ ComPtr<IPackageStatics> statics;
+ if (FAILED(GetActivationFactory(HStringReference(RuntimeClass_Windows_ApplicationModel_Package).Get(), &statics)))
+ return ret;
+ ComPtr<IPackage> package;
+ if (FAILED(statics->get_Current(&package)))
+ return ret;
+ ComPtr<IStorageFolder> installedLocation;
+ if (FAILED(package->get_InstalledLocation(&installedLocation)))
+ return ret;
+
+ ComPtr<IStorageItem> item;
+ if (FAILED(installedLocation.As(&item)))
+ return ret;
+
+ HSTRING finalWinPath;
+ if (FAILED(item->get_Path(&finalWinPath)))
+ return ret;
+
+ ret = QDir::fromNativeSeparators(QString::fromWCharArray(WindowsGetStringRawBuffer(finalWinPath, nullptr)));
+
#else
QString ret = QString::fromLatin1(qgetenv("SystemDrive").constData());
if (ret.isEmpty())
@@ -1158,12 +1269,13 @@ QString QFileSystemEngine::homePath()
QString QFileSystemEngine::tempPath()
{
QString ret;
+#ifndef Q_OS_WINRT
wchar_t tempPath[MAX_PATH];
const DWORD len = GetTempPath(MAX_PATH, tempPath);
#ifdef Q_OS_WINCE
if (len)
ret = QString::fromWCharArray(tempPath, len);
-#else
+#else // Q_OS_WINCE
if (len) { // GetTempPath() can return short names, expand.
wchar_t longTempPath[MAX_PATH];
const DWORD longLen = GetLongPathName(tempPath, longTempPath, MAX_PATH);
@@ -1171,12 +1283,33 @@ QString QFileSystemEngine::tempPath()
QString::fromWCharArray(longTempPath, longLen) :
QString::fromWCharArray(tempPath, len);
}
-#endif
+#endif // !Q_OS_WINCE
if (!ret.isEmpty()) {
while (ret.endsWith(QLatin1Char('\\')))
ret.chop(1);
ret = QDir::fromNativeSeparators(ret);
}
+#else // !Q_OS_WINRT
+ // According to http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.temporaryfolder.aspx
+ // the API is not available on winphone which should cause one of the functions
+ // below to fail
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ return ret;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ return ret;
+ ComPtr<IStorageFolder> tempFolder;
+ if (FAILED(applicationData->get_TemporaryFolder(&tempFolder)))
+ return ret;
+ ComPtr<IStorageItem> tempFolderItem;
+ if (FAILED(tempFolder.As(&tempFolderItem)))
+ return ret;
+ HSTRING path;
+ if (FAILED(tempFolderItem->get_Path(&path)))
+ return ret;
+ ret = QDir::fromNativeSeparators(QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr)));
+#endif // Q_OS_WINRT
if (ret.isEmpty()) {
#if !defined(Q_OS_WINCE)
ret = QLatin1String("C:/tmp");
@@ -1195,7 +1328,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
if(!(meta.exists() && meta.isDirectory()))
return false;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
//TODO: this should really be using nativeFilePath(), but that returns a path in long format \\?\c:\foo
//which causes many problems later on when it's returned through currentPath()
return ::SetCurrentDirectory(reinterpret_cast<const wchar_t*>(QDir::toNativeSeparators(entry.filePath()).utf16())) != 0;
@@ -1208,7 +1341,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
QFileSystemEntry QFileSystemEngine::currentPath()
{
QString ret;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
DWORD size = 0;
wchar_t currentName[PATH_MAX];
size = ::GetCurrentDirectory(PATH_MAX, currentName);
@@ -1224,13 +1357,17 @@ QFileSystemEntry QFileSystemEngine::currentPath()
}
if (ret.length() >= 2 && ret[1] == QLatin1Char(':'))
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
-#else
+#else // !Q_OS_WINCE && !Q_OS_WINRT
//TODO - a race condition exists when using currentPath / setCurrentPath from multiple threads
if (qfsPrivateCurrentDir.isEmpty())
+#ifndef Q_OS_WINRT
qfsPrivateCurrentDir = QCoreApplication::applicationDirPath();
+#else
+ qfsPrivateCurrentDir = QDir::rootPath();
+#endif
ret = qfsPrivateCurrentDir;
-#endif
+#endif // Q_OS_WINCE || Q_OS_WINRT
return QFileSystemEntry(ret, QFileSystemEntry::FromNativePath());
}
@@ -1248,8 +1385,16 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy
//static
bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
+#ifndef Q_OS_WINRT
bool ret = ::CopyFile((wchar_t*)source.nativeFilePath().utf16(),
(wchar_t*)target.nativeFilePath().utf16(), true) != 0;
+#else // !Q_OS_WINRT
+ COPYFILE2_EXTENDED_PARAMETERS copyParams = {
+ sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL
+ };
+ bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
+ (const wchar_t*)target.nativeFilePath().utf16(), &copyParams) != 0;
+#endif // Q_OS_WINRT
if(!ret)
error = QSystemError(::GetLastError(), QSystemError::NativeError);
return ret;
@@ -1258,8 +1403,13 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst
//static
bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
+#ifndef Q_OS_WINRT
bool ret = ::MoveFile((wchar_t*)source.nativeFilePath().utf16(),
(wchar_t*)target.nativeFilePath().utf16()) != 0;
+#else // !Q_OS_WINRT
+ bool ret = ::MoveFileEx((const wchar_t*)source.nativeFilePath().utf16(),
+ (const wchar_t*)target.nativeFilePath().utf16(), 0) != 0;
+#endif // Q_OS_WINRT
if(!ret)
error = QSystemError(::GetLastError(), QSystemError::NativeError);
return ret;
diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp
index 3934c6a673..42a724670e 100644
--- a/src/corelib/io/qfilesystementry.cpp
+++ b/src/corelib/io/qfilesystementry.cpp
@@ -170,6 +170,12 @@ void QFileSystemEntry::resolveNativeFilePath() const
#else
m_nativeFilePath = QFile::encodeName(QDir::toNativeSeparators(m_filePath));
#endif
+#ifdef Q_OS_WINRT
+ while (m_nativeFilePath.startsWith(QLatin1Char('\\')))
+ m_nativeFilePath.remove(0,1);
+ if (m_nativeFilePath.isEmpty())
+ m_nativeFilePath.append(QLatin1Char('.'));
+#endif
}
}
diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp
index bfedd3f70c..0b59aa169a 100644
--- a/src/corelib/io/qfilesystemiterator_unix.cpp
+++ b/src/corelib/io/qfilesystemiterator_unix.cpp
@@ -105,8 +105,8 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa
if (!dir)
return false;
-#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R)
- lastError = _readdir_r(dir, mt_file.data(), &dirEntry, direntSize);
+#if defined(Q_OS_QNX) && defined(QT_EXT_QNX_READDIR_R)
+ lastError = QT_EXT_QNX_READDIR_R(dir, mt_file.data(), &dirEntry, direntSize);
if (lastError)
return false;
#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN)
diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp
index 90232f7cfc..dda96bd45a 100644
--- a/src/corelib/io/qfilesystemiterator_win.cpp
+++ b/src/corelib/io/qfilesystemiterator_win.cpp
@@ -39,10 +39,12 @@
**
****************************************************************************/
-#if _WIN32_WINNT < 0x0500
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
-#endif
+#if !defined(WINAPI_FAMILY)
+# if _WIN32_WINNT < 0x0500
+# undef _WIN32_WINNT
+# define _WIN32_WINNT 0x0500
+# endif // _WIN32_WINNT < 0x500
+#endif // !WINAPI_FAMILY
#include "qfilesystemiterator_p.h"
#include "qfilesystemengine_p.h"
@@ -73,6 +75,10 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
if (!nativePath.endsWith(QLatin1Char('\\')))
nativePath.append(QLatin1Char('\\'));
nativePath.append(QLatin1Char('*'));
+#ifdef Q_OS_WINRT
+ if (nativePath.startsWith(QLatin1Char('\\')))
+ nativePath.remove(0, 1);
+#endif
if (!dirPath.endsWith(QLatin1Char('/')))
dirPath.append(QLatin1Char('/'));
if ((filters & (QDir::Dirs|QDir::Drives)) && (!(filters & (QDir::Files))))
diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h
index 1abc9b7ec4..de79ec32d3 100644
--- a/src/corelib/io/qfilesystemmetadata_p.h
+++ b/src/corelib/io/qfilesystemmetadata_p.h
@@ -219,7 +219,9 @@ public:
#if defined(Q_OS_WIN)
inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false);
inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false);
+# ifndef Q_OS_WINRT
inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo);
+# endif
#endif
private:
friend class QFileSystemEngine;
@@ -340,6 +342,7 @@ inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, boo
}
}
+#ifndef Q_OS_WINRT
inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo)
{
fillFromFileAttribute(fileInfo.dwFileAttributes);
@@ -355,7 +358,8 @@ inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fi
}
knownFlagsMask |= Times | SizeAttribute;
}
-#endif
+#endif // !Q_OS_WINRT
+#endif // Q_OS_WIN
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index c731f3d417..5fd20c6d74 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -129,9 +129,9 @@
# define __NR_inotify_rm_watch 271
# define __NR_inotify_init1 314
#elif defined (__avr32__)
-# define __NR_inotify_init 240
-# define __NR_inotify_add_watch 241
-# define __NR_inotify_rm_watch 242
+# define __NR_inotify_init 240
+# define __NR_inotify_add_watch 241
+# define __NR_inotify_rm_watch 242
// no inotify_init1 for AVR32
#elif defined (__mc68000__)
# define __NR_inotify_init 284
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index a5f077bd0b..064a1a511f 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -45,6 +45,7 @@
#include "private/qcore_unix_p.h"
#include "qfilesystementry_p.h"
#include "qfilesystemengine_p.h"
+#include "qcoreapplication.h"
#ifndef QT_NO_FSFILEENGINE
@@ -142,6 +143,16 @@ static inline bool setCloseOnExec(int fd)
return fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) != -1;
}
+static inline QString msgOpenDirectory()
+{
+ const char message[] = QT_TRANSLATE_NOOP("QIODevice", "file to open is a directory");
+#ifndef QT_BOOTSTRAPPED
+ return QIODevice::tr(message);
+#else
+ return QLatin1String(message);
+#endif
+}
+
/*!
\internal
*/
@@ -169,7 +180,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
// we had received EISDIR anyway.
if (QFileSystemEngine::fillMetaData(fd, metaData)
&& metaData.isDirectory()) {
- q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
+ q->setError(QFile::OpenError, msgOpenDirectory());
QT_CLOSE(fd);
return false;
}
@@ -210,7 +221,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
// we had received EISDIR anyway.
if (QFileSystemEngine::fillMetaData(QT_FILENO(fh), metaData)
&& metaData.isDirectory()) {
- q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
+ q->setError(QFile::OpenError, msgOpenDirectory());
fclose(fh);
return false;
}
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 2b38019674..c974daab06 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -60,14 +60,18 @@
# include <types.h>
#endif
#include <objbase.h>
-#include <shlobj.h>
+#ifndef Q_OS_WINRT
+# include <shlobj.h>
+# include <accctrl.h>
+#endif
#include <initguid.h>
-#include <accctrl.h>
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
-#define SECURITY_WIN32
-#include <security.h>
+#ifndef Q_OS_WINRT
+# define SECURITY_WIN32
+# include <security.h>
+#endif
#ifndef PATH_MAX
#define PATH_MAX FILENAME_MAX
@@ -93,7 +97,7 @@ QString QFSFileEnginePrivate::longFileName(const QString &path)
return path;
QString absPath = QFileSystemEngine::nativeAbsoluteFilePath(path);
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QString prefix = QLatin1String("\\\\?\\");
if (isUncPath(absPath)) {
prefix.append(QLatin1String("UNC\\")); // "\\\\?\\UNC\\"
@@ -121,11 +125,12 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
if (openMode & QIODevice::WriteOnly)
accessRights |= GENERIC_WRITE;
- SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
// WriteOnly can create files, ReadOnly cannot.
DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING;
// Create the file handle.
+#ifndef Q_OS_WINRT
+ SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
accessRights,
shareMode,
@@ -133,6 +138,13 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
creationDisp,
FILE_ATTRIBUTE_NORMAL,
NULL);
+#else // !Q_OS_WINRT
+ fileHandle = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(),
+ accessRights,
+ shareMode,
+ creationDisp,
+ NULL);
+#endif // Q_OS_WINRT
// Bail out on error.
if (fileHandle == INVALID_HANDLE_VALUE) {
@@ -473,7 +485,7 @@ int QFSFileEnginePrivate::nativeHandle() const
*/
bool QFSFileEnginePrivate::nativeIsSequential() const
{
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
HANDLE handle = fileHandle;
if (fh || fd != -1)
handle = (HANDLE)_get_osfhandle(fh ? QT_FILENO(fh) : fd);
@@ -577,7 +589,7 @@ bool QFSFileEngine::setCurrentPath(const QString &path)
QString QFSFileEngine::currentPath(const QString &fileName)
{
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QString ret;
//if filename is a drive: then get the pwd of that drive
if (fileName.length() >= 2 &&
@@ -596,10 +608,10 @@ QString QFSFileEngine::currentPath(const QString &fileName)
if (ret.length() >= 2 && ret[1] == QLatin1Char(':'))
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
return ret;
-#else
+#else // !Q_OS_WINCE && !Q_OS_WINRT
Q_UNUSED(fileName);
return QFileSystemEngine::currentPath().filePath();
-#endif
+#endif // Q_OS_WINCE || Q_OS_WINRT
}
QString QFSFileEngine::homePath()
@@ -620,7 +632,7 @@ QString QFSFileEngine::tempPath()
QFileInfoList QFSFileEngine::drives()
{
QFileInfoList ret;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#if defined(Q_OS_WIN32)
quint32 driveBits = (quint32) GetLogicalDrives() & 0x3ffffff;
#endif
@@ -633,10 +645,10 @@ QFileInfoList QFSFileEngine::drives()
driveBits = driveBits >> 1;
}
return ret;
-#else
+#else // !Q_OS_WINCE && !Q_OS_WINRT
ret.append(QFileInfo(QLatin1String("/")));
return ret;
-#endif
+#endif // Q_OS_WINCE || Q_OS_WINRT
}
bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const
@@ -661,7 +673,7 @@ bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) cons
bool QFSFileEngine::link(const QString &newName)
{
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#if !defined(QT_NO_LIBRARY)
bool ret = false;
@@ -707,7 +719,7 @@ bool QFSFileEngine::link(const QString &newName)
Q_UNUSED(newName);
return false;
#endif // QT_NO_LIBRARY
-#else
+#elif defined(Q_OS_WINCE)
QString linkName = newName;
linkName.replace(QLatin1Char('/'), QLatin1Char('\\'));
if (!linkName.endsWith(QLatin1String(".lnk")))
@@ -720,7 +732,11 @@ bool QFSFileEngine::link(const QString &newName)
if (!ret)
setError(QFile::RenameError, qt_error_string());
return ret;
-#endif // Q_OS_WINCE
+#else // Q_OS_WINCE
+ Q_UNUSED(newName);
+ Q_UNIMPLEMENTED();
+ return false;
+#endif // Q_OS_WINRT
}
/*!
@@ -937,6 +953,7 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
QFile::MemoryMapFlags flags)
{
+#ifndef Q_OS_WINPHONE
Q_Q(QFSFileEngine);
Q_UNUSED(flags);
if (openMode == QFile::NotOpen) {
@@ -980,7 +997,11 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
// first create the file mapping handle
DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY;
+#ifndef Q_OS_WINRT
mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0);
+#else
+ mapHandle = ::CreateFileMappingFromApp(handle, 0, protection, 0, 0);
+#endif
if (mapHandle == NULL) {
q->setError(QFile::PermissionsError, qt_error_string());
#ifdef Q_USE_DEPRECATED_MAP_API
@@ -998,15 +1019,23 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
DWORD offsetHi = offset >> 32;
DWORD offsetLo = offset & Q_UINT64_C(0xffffffff);
SYSTEM_INFO sysinfo;
+#ifndef Q_OS_WINRT
::GetSystemInfo(&sysinfo);
+#else
+ ::GetNativeSystemInfo(&sysinfo);
+#endif
DWORD mask = sysinfo.dwAllocationGranularity - 1;
DWORD extra = offset & mask;
if (extra)
offsetLo &= ~mask;
// attempt to create the map
+#ifndef Q_OS_WINRT
LPVOID mapAddress = ::MapViewOfFile(mapHandle, access,
offsetHi, offsetLo, size + extra);
+#else
+ LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access, offset, size);
+#endif
if (mapAddress) {
uchar *address = extra + static_cast<uchar*>(mapAddress);
maps[address] = extra;
@@ -1025,11 +1054,18 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
::CloseHandle(mapHandle);
mapHandle = NULL;
+#else // !Q_OS_WINPHONE
+ Q_UNUSED(offset);
+ Q_UNUSED(size);
+ Q_UNUSED(flags);
+ Q_UNIMPLEMENTED();
+#endif // Q_OS_WINPHONE
return 0;
}
bool QFSFileEnginePrivate::unmap(uchar *ptr)
{
+#ifndef Q_OS_WINPHONE
Q_Q(QFSFileEngine);
if (!maps.contains(ptr)) {
q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
@@ -1048,6 +1084,11 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
}
return true;
+#else // !Q_OS_WINPHONE
+ Q_UNUSED(ptr);
+ Q_UNIMPLEMENTED();
+ return false;
+#endif // Q_OS_WINPHONE
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp
index b5f6d9f3da..28f6b02a64 100644
--- a/src/corelib/io/qlockfile_win.cpp
+++ b/src/corelib/io/qlockfile_win.cpp
@@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE
QLockFile::LockError QLockFilePrivate::tryLock_sys()
{
- SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
const QFileSystemEntry fileEntry(fileName);
// When writing, allow others to read.
// When reading, QFile will allow others to read and write, all good.
@@ -60,6 +59,8 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
// but Windows doesn't allow recreating it while this handle is open anyway,
// so this would only create confusion (can't lock, but no lock file to read from).
const DWORD dwShareMode = FILE_SHARE_READ;
+#ifndef Q_OS_WINRT
+ SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
HANDLE fh = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
GENERIC_WRITE,
dwShareMode,
@@ -67,6 +68,13 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
CREATE_NEW, // error if already exists
FILE_ATTRIBUTE_NORMAL,
NULL);
+#else // !Q_OS_WINRT
+ HANDLE fh = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(),
+ GENERIC_WRITE,
+ dwShareMode,
+ CREATE_NEW, // error if already exists
+ NULL);
+#endif // Q_OS_WINRT
if (fh == INVALID_HANDLE_VALUE) {
const DWORD lastError = GetLastError();
switch (lastError) {
@@ -112,6 +120,9 @@ bool QLockFilePrivate::isApparentlyStale() const
if (!getLockInfo(&pid, &hostname, &appname))
return false;
+ // On WinRT there seems to be no way of obtaining information about other
+ // processes due to sandboxing
+#ifndef Q_OS_WINRT
HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!procHandle)
return true;
@@ -120,6 +131,7 @@ bool QLockFilePrivate::isApparentlyStale() const
::CloseHandle(procHandle);
if (dwR == WAIT_TIMEOUT)
return true;
+#endif // !Q_OS_WINRT
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
return staleLockTime > 0 && age > staleLockTime;
}
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index ab2a69d054..483650afcb 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -2388,14 +2388,14 @@ int QProcess::execute(const QString &program)
identifier of the started process.
*/
bool QProcess::startDetached(const QString &program,
- const QStringList &arguments,
- const QString &workingDirectory,
+ const QStringList &arguments,
+ const QString &workingDirectory,
qint64 *pid)
{
return QProcessPrivate::startDetached(program,
- arguments,
- workingDirectory,
- pid);
+ arguments,
+ workingDirectory,
+ pid);
}
/*!
@@ -2414,7 +2414,7 @@ bool QProcess::startDetached(const QString &program,
The started process will run as a regular standalone process.
*/
bool QProcess::startDetached(const QString &program,
- const QStringList &arguments)
+ const QStringList &arguments)
{
return QProcessPrivate::startDetached(program, arguments);
}
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 3c6d294916..4076ec5855 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -1107,7 +1107,7 @@ bool QProcessPrivate::waitForStarted(int msecs)
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForStarted(%d) waiting for child to start (fd = %d)", msecs,
- childStartedPipe[0]);
+ childStartedPipe[0]);
#endif
fd_set fds;
@@ -1172,32 +1172,32 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
if (ret == 0) {
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
- return false;
- }
+ return false;
+ }
- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
+ if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
if (!_q_startupNotification())
return false;
- }
+ }
bool readyReadEmitted = false;
- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) {
- bool canRead = _q_canReadStandardOutput();
+ if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) {
+ bool canRead = _q_canReadStandardOutput();
if (processChannel == QProcess::StandardOutput && canRead)
readyReadEmitted = true;
- }
- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) {
- bool canRead = _q_canReadStandardError();
+ }
+ if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) {
+ bool canRead = _q_canReadStandardError();
if (processChannel == QProcess::StandardError && canRead)
readyReadEmitted = true;
- }
+ }
if (readyReadEmitted)
return true;
- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
- _q_canWrite();
+ if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
+ _q_canWrite();
- if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
+ if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
if (_q_processDied())
return false;
}
@@ -1248,26 +1248,26 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
}
if (ret == 0) {
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
- return false;
- }
+ processError = QProcess::Timedout;
+ q->setErrorString(QProcess::tr("Process operation timed out"));
+ return false;
+ }
- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
- if (!_q_startupNotification())
- return false;
- }
+ if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
+ if (!_q_startupNotification())
+ return false;
+ }
- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
- return _q_canWrite();
+ if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
+ return _q_canWrite();
- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
- _q_canReadStandardOutput();
+ if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
+ _q_canReadStandardOutput();
- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
- _q_canReadStandardError();
+ if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
+ _q_canReadStandardError();
- if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
+ if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
if (_q_processDied())
return false;
}
@@ -1317,29 +1317,29 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (ret < 0) {
break;
}
- if (ret == 0) {
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
- return false;
- }
-
- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
- if (!_q_startupNotification())
- return false;
- }
- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
- _q_canWrite();
-
- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
- _q_canReadStandardOutput();
-
- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
- _q_canReadStandardError();
-
- if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
+ if (ret == 0) {
+ processError = QProcess::Timedout;
+ q->setErrorString(QProcess::tr("Process operation timed out"));
+ return false;
+ }
+
+ if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
+ if (!_q_startupNotification())
+ return false;
+ }
+ if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
+ _q_canWrite();
+
+ if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
+ _q_canReadStandardOutput();
+
+ if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
+ _q_canReadStandardError();
+
+ if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
if (_q_processDied())
return true;
- }
+ }
}
return false;
}
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index fc2adb783e..d7050034bd 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -623,7 +623,7 @@ static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)
DWORD currentProcId = 0;
GetWindowThreadProcessId(hwnd, &currentProcId);
if (currentProcId == (DWORD)procId)
- PostMessage(hwnd, WM_CLOSE, 0, 0);
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
return TRUE;
}
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index c16b8d79a2..bfd0eef64f 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1092,8 +1092,8 @@ QResource::unregisterResource(const QString &rccFilename, const QString &resourc
for(int i = 0; i < list->size(); ++i) {
QResourceRoot *res = list->at(i);
if(res->type() == QResourceRoot::Resource_File) {
- QDynamicFileResourceRoot *root = reinterpret_cast<QDynamicFileResourceRoot*>(res);
- if(root->mappingFile() == rccFilename && root->mappingRoot() == r) {
+ QDynamicFileResourceRoot *root = reinterpret_cast<QDynamicFileResourceRoot*>(res);
+ if (root->mappingFile() == rccFilename && root->mappingRoot() == r) {
resourceList()->removeAt(i);
if(!root->ref.deref()) {
delete root;
@@ -1101,7 +1101,7 @@ QResource::unregisterResource(const QString &rccFilename, const QString &resourc
}
return false;
}
- }
+ }
}
return false;
}
@@ -1163,16 +1163,16 @@ QResource::unregisterResource(const uchar *rccData, const QString &resourceRoot)
for(int i = 0; i < list->size(); ++i) {
QResourceRoot *res = list->at(i);
if(res->type() == QResourceRoot::Resource_Buffer) {
- QDynamicBufferResourceRoot *root = reinterpret_cast<QDynamicBufferResourceRoot*>(res);
- if(root->mappingBuffer() == rccData && root->mappingRoot() == r) {
+ QDynamicBufferResourceRoot *root = reinterpret_cast<QDynamicBufferResourceRoot*>(res);
+ if (root->mappingBuffer() == rccData && root->mappingRoot() == r) {
resourceList()->removeAt(i);
if(!root->ref.deref()) {
delete root;
return true;
}
- return false;
+ return false;
}
- }
+ }
}
return false;
}
@@ -1381,13 +1381,13 @@ QString QResourceFileEngine::fileName(FileName file) const
{
Q_D(const QResourceFileEngine);
if(file == BaseName) {
- int slash = d->resource.fileName().lastIndexOf(QLatin1Char('/'));
- if (slash == -1)
- return d->resource.fileName();
- return d->resource.fileName().mid(slash + 1);
+ int slash = d->resource.fileName().lastIndexOf(QLatin1Char('/'));
+ if (slash == -1)
+ return d->resource.fileName();
+ return d->resource.fileName().mid(slash + 1);
} else if(file == PathName || file == AbsolutePathName) {
const QString path = (file == AbsolutePathName) ? d->resource.absoluteFilePath() : d->resource.fileName();
- const int slash = path.lastIndexOf(QLatin1Char('/'));
+ const int slash = path.lastIndexOf(QLatin1Char('/'));
if (slash == -1)
return QLatin1String(":");
else if (slash <= 1)
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 35b3ed4e3d..a3727a6a4b 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -78,14 +78,27 @@
#ifdef Q_OS_WIN // for homedirpath reading from registry
# include <private/qsystemlibrary_p.h>
# include <qt_windows.h>
+# ifndef Q_OS_WINRT
+# include <shlobj.h>
+# endif
+#endif
+
+#ifdef Q_OS_WINRT
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
#endif
#ifndef CSIDL_COMMON_APPDATA
-#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
+#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
#endif
#ifndef CSIDL_APPDATA
-#define CSIDL_APPDATA 0x001a // <username>\Application Data
+#define CSIDL_APPDATA 0x001a // <username>\Application Data
#endif
#ifdef Q_AUTOTEST_EXPORT
@@ -365,7 +378,7 @@ after_loop:
// see also qsettings_win.cpp and qsettings_mac.cpp
-#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
+#if defined(Q_OS_WINRT) || (!defined(Q_OS_WIN) && !defined(Q_OS_MAC))
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,
const QString &organization, const QString &application)
{
@@ -373,7 +386,7 @@ QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::
}
#endif
-#if !defined(Q_OS_WIN)
+#if defined(Q_OS_WINRT) || !defined(Q_OS_WIN)
QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::Format format)
{
return new QConfFileSettingsPrivate(fileName, format);
@@ -1021,23 +1034,14 @@ void QConfFileSettingsPrivate::initAccess()
sync(); // loads the files the first time
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static QString windowsConfigPath(int type)
{
QString result;
-#ifndef Q_OS_WINCE
- QSystemLibrary library(QLatin1String("shell32"));
-#else
- QSystemLibrary library(QLatin1String("coredll"));
-#endif // Q_OS_WINCE
- typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
- GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
- if (SHGetSpecialFolderPath) {
- wchar_t path[MAX_PATH];
- SHGetSpecialFolderPath(0, path, type, false);
+ wchar_t path[MAX_PATH];
+ if (SHGetSpecialFolderPath(0, path, type, false))
result = QString::fromWCharArray(path);
- }
if (result.isEmpty()) {
switch (type) {
@@ -1063,7 +1067,40 @@ static QString windowsConfigPath(int type)
return result;
}
-#endif // Q_OS_WIN
+#elif defined(Q_OS_WINRT) // Q_OS_WIN && !Q_OS_WINRT
+static QString windowsConfigPath(int type)
+{
+ static QString result;
+ while (result.isEmpty()) {
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ return result;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ return result;
+ ComPtr<IStorageFolder> localFolder;
+ if (FAILED(applicationData->get_LocalFolder(&localFolder)))
+ return result;
+ ComPtr<IStorageItem> localFolderItem;
+ if (FAILED(localFolder.As(&localFolderItem)))
+ return result;
+ HSTRING path;
+ if (FAILED(localFolderItem->get_Path(&path)))
+ return result;
+ result = QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr));
+ }
+
+ switch (type) {
+ case CSIDL_COMMON_APPDATA:
+ return result + QLatin1String("\\qt-common");
+ case CSIDL_APPDATA:
+ return result + QLatin1String("\\qt-user");
+ default:
+ break;
+ }
+ return result;
+}
+#endif // Q_OS_WINRT
static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope)
{
@@ -1449,10 +1486,18 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QString writeSemName = QLatin1String("QSettingsWriteSem ");
writeSemName.append(file.fileName());
+#ifndef Q_OS_WINRT
writeSemaphore = CreateSemaphore(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()));
+#else
+ writeSemaphore = CreateSemaphoreEx(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
+#endif
if (writeSemaphore) {
+#ifndef Q_OS_WINRT
WaitForSingleObject(writeSemaphore, INFINITE);
+#else
+ WaitForSingleObjectEx(writeSemaphore, INFINITE, FALSE);
+#endif
} else {
setStatus(QSettings::AccessError);
return;
@@ -1465,11 +1510,19 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QString readSemName(QLatin1String("QSettingsReadSem "));
readSemName.append(file.fileName());
+#ifndef Q_OS_WINRT
readSemaphore = CreateSemaphore(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()));
+#else
+ readSemaphore = CreateSemaphoreEx(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
+#endif
if (readSemaphore) {
for (int i = 0; i < numReadLocks; ++i)
+#ifndef Q_OS_WINRT
WaitForSingleObject(readSemaphore, INFINITE);
+#else
+ WaitForSingleObjectEx(readSemaphore, INFINITE, FALSE);
+#endif
} else {
setStatus(QSettings::AccessError);
if (writeSemaphore != 0) {
diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h
index a720b3d709..f44b99d009 100644
--- a/src/corelib/io/qsettings.h
+++ b/src/corelib/io/qsettings.h
@@ -117,7 +117,7 @@ public:
QSettings(Scope scope, const QString &organization,
const QString &application = QString(), QObject *parent = 0);
QSettings(Format format, Scope scope, const QString &organization,
- const QString &application = QString(), QObject *parent = 0);
+ const QString &application = QString(), QObject *parent = 0);
QSettings(const QString &fileName, Format format, QObject *parent = 0);
explicit QSettings(QObject *parent = 0);
#else
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 2207b8c43e..c145ec4bad 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -72,34 +72,199 @@ QT_BEGIN_NAMESPACE
methods such as QStandardPaths::writableLocation, QStandardPaths::standardLocations,
and QStandardPaths::displayName.
- \value DesktopLocation Returns the user's desktop directory.
- \value DocumentsLocation Returns the user's document.
- \value FontsLocation Returns the user's fonts.
- \value ApplicationsLocation Returns the user's applications.
- \value MusicLocation Returns the user's music.
- \value MoviesLocation Returns the user's movies.
- \value PicturesLocation Returns the user's pictures.
- \value TempLocation Returns the system's temporary directory.
- \value HomeLocation Returns the user's home directory.
+ Some of the values in this enum represent a user configuration. Such enum
+ values will return the same paths in different applications, so they could
+ be used to share data with other applications. Other values are specific to
+ this application. Each enum value in the table below describes whether it's
+ application-specific or generic.
+
+ Application-specific directories should be assumed to be unreachable by
+ other applications. Therefore, files placed there might not be readable by
+ other applications, even if run by the same user. On the other hand, generic
+ directories should be assumed to be accessible by all applications run by
+ this user, but should still be assumed to be unreachable by applications by
+ other users.
+
+ The only exception is QStandardPaths::TempLocation (which is the same as
+ QDir::tempPath()): the path returned may be application-specific, but files
+ stored there may be accessed by other applications run by the same user.
+
+ Data interchange with other users is out of the scope of QStandardPaths.
+
+ \value DesktopLocation Returns the user's desktop directory. This is a generic value.
+ On systems with no concept of a desktop, this is the same as
+ QStandardPaths::HomeLocation.
+ \value DocumentsLocation Returns the directory containing user document files.
+ This is a generic value. The returned path is never empty.
+ \value FontsLocation Returns the directory containing user's fonts. This is a generic value.
+ Note that installing fonts may require additional, platform-specific operations.
+ \value ApplicationsLocation Returns the directory containing the user applications
+ (either executables, application bundles, or shortcuts to them). This is a generic value.
+ Note that installing applications may require additional, platform-specific operations.
+ Files, folders or shortcuts in this directory are platform-specific.
+ \value MusicLocation Returns the directory containing the user's music or other audio files.
+ This is a generic value. If no directory specific for music files exists, a sensible
+ fallback for storing user documents is returned.
+ \value MoviesLocation Returns the directory containing the user's movies and videos.
+ This is a generic value. If no directory specific for movie files exists, a sensible
+ fallback for storing user documents is returned.
+ \value PicturesLocation Returns the directory containing the user's pictures or photos.
+ This is a generic value. If no directory specific for picture files exists, a sensible
+ fallback for storing user documents is returned.
+ \value TempLocation Returns a directory where temporary files can be stored. The returned value
+ might be application-specific, shared among other applications for this user, or even
+ system-wide. The returned path is never empty.
+ \value HomeLocation Returns the user's home directory (the same as QDir::homePath()). On Unix
+ systems, this is equal to the HOME environment variable. This value might be
+ generic or application-specific, but the returned path is never empty.
\value DataLocation Returns a directory location where persistent
- application data can be stored. QCoreApplication::organizationName
- and QCoreApplication::applicationName are appended to the directory location
- returned for GenericDataLocation.
+ application data can be stored. This is an application-specific directory. To obtain a
+ path to store data to be shared with other applications, use
+ QStandardPaths::GenericDataLocation. The returned path is never empty.
\value CacheLocation Returns a directory location where user-specific
- non-essential (cached) data should be written.
- \value GenericCacheLocation Returns a directory location where user-specific
- non-essential (cached) data, shared across applications, should be written.
+ non-essential (cached) data should be written. This is an application-specific directory.
+ The returned path is never empty.
+ \value GenericCacheLocation Returns a directory location where user-specific non-essential
+ (cached) data, shared across applications, should be written. This is a generic value.
+ Note that the returned path may be empty if the system has no concept of shared cache.
\value GenericDataLocation Returns a directory location where persistent
- data shared across applications can be stored.
+ data shared across applications can be stored. This is a generic value. The returned
+ path is never empty.
\value RuntimeLocation Returns a directory location where runtime communication
- files should be written. For instance unix local sockets.
+ files should be written, like Unix local sockets. This is a generic value.
+ The returned path may be empty on some systems.
\value ConfigLocation Returns a directory location where user-specific
- configuration files should be written.
+ configuration files should be written. This may be either a generic value
+ or application-specific, and the returned path is never empty.
+ \value DownloadLocation Returns a directory for user's downloaded files. This is a generic value.
+ If no directory specific for downloads exists, a sensible fallback for storing user
+ documents is returned.
\value GenericConfigLocation Returns a directory location where user-specific
configuration files shared between multiple applications should be written.
This is a generic value and the returned path is never empty.
- \value DownloadLocation Returns a directory for user's downloaded files.
+ The following table gives examples of paths on different operating systems.
+ The first path is the writable path (unless noted). Other, additional
+ paths, if any, represent non-writable locations.
+
+ \table
+ \header \li Path type \li OS X \li Windows
+ \row \li DesktopLocation
+ \li "~/Desktop"
+ \li "C:/Users/<USER>/Desktop"
+ \row \li DocumentsLocation
+ \li "~/Documents"
+ \li "C:/Users/<USER>/Documents"
+ \row \li FontsLocation
+ \li "/System/Library/Fonts" (not writable)
+ \li "C:/Windows/Fonts" (not writable)
+ \row \li ApplicationsLocation
+ \li "/Applications" (not writable)
+ \li "C:/Users/<USER>/AppData/Roaming/Microsoft/Windows/Start Menu/Programs"
+ \row \li MusicLocation
+ \li "~/Music"
+ \li "C:/Users/<USER>/Music"
+ \row \li MoviesLocation
+ \li "~/Movies"
+ \li "C:/Users/<USER>/Videos"
+ \row \li PicturesLocation
+ \li "~/Pictures"
+ \li "C:/Users/<USER>/Pictures"
+ \row \li TempLocation
+ \li randomly generated by the OS
+ \li "C:/Users/<USER>/AppData/Local/Temp"
+ \row \li HomeLocation
+ \li "~"
+ \li "C:/Users/<USER>"
+ \row \li DataLocation
+ \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data"
+ \row \li CacheLocation
+ \li "~/Library/Caches/<APPNAME>", "/Library/Caches/<APPNAME>"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache"
+ \row \li GenericDataLocation
+ \li "~/Library/Application Support", "/Library/Application Support"
+ \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
+ \row \li RuntimeLocation
+ \li "~/Library/Application Support"
+ \li "C:/Users/<USER>"
+ \row \li ConfigLocation
+ \li "~/Library/Preferences"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>"
+ \row \li GenericConfigLocation
+ \li "~/Library/Preferences"
+ \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
+ \row \li DownloadLocation
+ \li "~/Documents"
+ \li "C:/Users/<USER>/Documents"
+ \row \li GenericCacheLocation
+ \li "~/Library/Caches", "/Library/Caches"
+ \li "C:/Users/<USER>/AppData/Local/cache"
+ \endtable
+
+ \table
+ \header \li Path type \li Blackberry \li Linux (including Android)
+ \row \li DesktopLocation
+ \li "<APPROOT>/data"
+ \li "~/Desktop"
+ \row \li DocumentsLocation
+ \li "<APPROOT>/shared/documents"
+ \li "~/Documents"
+ \row \li FontsLocation
+ \li "/base/usr/fonts" (not writable)
+ \li "~/.fonts"
+ \row \li ApplicationsLocation
+ \li not supported (directory not readable)
+ \li "~/.local/share/applications", "/usr/local/share/applications", "/usr/share/applications"
+ \row \li MusicLocation
+ \li "<APPROOT>/shared/music"
+ \li "~/Music"
+ \row \li MoviesLocation
+ \li "<APPROOT>/shared/videos"
+ \li "~/Videos"
+ \row \li PicturesLocation
+ \li "<APPROOT>/shared/photos"
+ \li "~/Pictures"
+ \row \li TempLocation
+ \li "/var/tmp"
+ \li "/tmp"
+ \row \li HomeLocation
+ \li "<APPROOT>/data"
+ \li "~"
+ \row \li DataLocation
+ \li "<APPROOT>/data", "<APPROOT>/app/native/assets"
+ \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
+ \row \li CacheLocation
+ \li "<APPROOT>/data/Cache"
+ \li "~/.cache/<APPNAME>"
+ \row \li GenericDataLocation
+ \li "<APPROOT>/shared/misc"
+ \li "~/.local/share", "/usr/local/share", "/usr/share"
+ \row \li RuntimeLocation
+ \li "/var/tmp"
+ \li "/run/user/<USER>"
+ \row \li ConfigLocation
+ \li "<APPROOT>/data/Settings"
+ \li "~/.config", "/etc/xdg"
+ \row \li GenericConfigLocation
+ \li "<APPROOT>/data/Settings"
+ \li "~/.config", "/etc/xdg"
+ \row \li DownloadLocation
+ \li "<APPROOT>/shared/downloads"
+ \li "~/Downloads"
+ \row \li GenericCacheLocation
+ \li "<APPROOT>/data/Cache" (there is no shared cache)
+ \li "~/.cache"
+ \endtable
+
+ In the table above, \c <APPNAME> is usually the organization name, the
+ application name, or both, or a unique name generated at packaging.
+ Similarly, <APPROOT> is the location where this application is installed
+ (often a sandbox). <APPDIR> is the directory containing the application
+ executable.
+
+ The paths above should not be relied upon, as they may change according to
+ OS configuration, locale, or they may change in future Qt versions.
\sa writableLocation(), standardLocations(), displayName(), locate(), locateAll()
*/
diff --git a/src/corelib/io/qstandardpaths_blackberry.cpp b/src/corelib/io/qstandardpaths_blackberry.cpp
index 815756ff9a..ec2e61bd15 100644
--- a/src/corelib/io/qstandardpaths_blackberry.cpp
+++ b/src/corelib/io/qstandardpaths_blackberry.cpp
@@ -103,10 +103,17 @@ QString QStandardPaths::writableLocation(StandardLocation type)
QStringList QStandardPaths::standardLocations(StandardLocation type)
{
+ QStringList dirs;
+
if (type == FontsLocation)
return QStringList(QLatin1String("/base/usr/fonts"));
- return QStringList(writableLocation(type));
+ if (type == DataLocation)
+ dirs.append(QDir::homePath() + testModeInsert() + QLatin1String("native/assets"));
+
+ const QString localDir = writableLocation(type);
+ dirs.prepend(localDir);
+ return dirs;
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qstandardpaths_mac.cpp b/src/corelib/io/qstandardpaths_mac.cpp
index 0efdfae253..aff9112fb7 100644
--- a/src/corelib/io/qstandardpaths_mac.cpp
+++ b/src/corelib/io/qstandardpaths_mac.cpp
@@ -47,6 +47,7 @@
#include <qcoreapplication.h>
#endif
+#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
QT_BEGIN_NAMESPACE
@@ -184,6 +185,30 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
dirs.append(path);
}
+ if (type == DataLocation) {
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ if (mainBundle) {
+ CFURLRef bundleUrl = CFBundleCopyBundleURL(mainBundle);
+ CFStringRef cfBundlePath = CFURLCopyPath(bundleUrl);
+ QString bundlePath = QCFString::toQString(cfBundlePath);
+ CFRelease(cfBundlePath);
+ CFRelease(bundleUrl);
+
+ CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(mainBundle);
+ CFStringRef cfResourcesPath = CFURLCopyPath(bundleUrl);
+ QString resourcesPath = QCFString::toQString(cfResourcesPath);
+ CFRelease(cfResourcesPath);
+ CFRelease(resourcesUrl);
+
+ // Handle bundled vs unbundled executables. CFBundleGetMainBundle() returns
+ // a valid bundle in both cases. CFBundleCopyResourcesDirectoryURL() returns
+ // an absolute path for unbundled executables.
+ if (resourcesPath.startsWith(QLatin1Char('/')))
+ dirs.append(resourcesPath);
+ else
+ dirs.append(bundlePath + resourcesPath);
+ }
+ }
const QString localDir = writableLocation(type);
dirs.prepend(localDir);
return dirs;
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index 6a79c7c00b..a0344a0206 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -68,21 +68,6 @@
QT_BEGIN_NAMESPACE
-typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
-static GetSpecialFolderPath resolveGetSpecialFolderPath()
-{
- static GetSpecialFolderPath gsfp = 0;
- if (!gsfp) {
-#ifndef Q_OS_WINCE
- QSystemLibrary library(QLatin1String("shell32"));
-#else
- QSystemLibrary library(QLatin1String("coredll"));
-#endif // Q_OS_WINCE
- gsfp = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
- }
- return gsfp;
-}
-
static QString convertCharArray(const wchar_t *path)
{
return QDir::fromNativeSeparators(QString::fromWCharArray(path));
@@ -92,10 +77,6 @@ QString QStandardPaths::writableLocation(StandardLocation type)
{
QString result;
- static GetSpecialFolderPath SHGetSpecialFolderPath = resolveGetSpecialFolderPath();
- if (!SHGetSpecialFolderPath)
- return QString();
-
wchar_t path[MAX_PATH];
switch (type) {
@@ -185,8 +166,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
// type-specific handling goes here
#ifndef Q_OS_WINCE
- static GetSpecialFolderPath SHGetSpecialFolderPath = resolveGetSpecialFolderPath();
- if (SHGetSpecialFolderPath) {
+ {
wchar_t path[MAX_PATH];
switch (type) {
case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it)
@@ -204,6 +184,12 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
#endif
}
dirs.append(result);
+#ifndef QT_BOOTSTRAPPED
+ if (type != GenericDataLocation) {
+ dirs.append(QCoreApplication::applicationDirPath());
+ dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data"));
+ }
+#endif
}
break;
default:
diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp
new file mode 100644
index 0000000000..9b6a088a30
--- /dev/null
+++ b/src/corelib/io/qstandardpaths_winrt.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstandardpaths.h"
+
+#include <qdir.h>
+#include <private/qsystemlibrary_p.h>
+#include <qcoreapplication.h>
+#include <qstringlist.h>
+
+#include <qt_windows.h>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+#include <Windows.ApplicationModel.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::ApplicationModel;
+
+#ifndef QT_NO_STANDARDPATHS
+
+QT_BEGIN_NAMESPACE
+
+static QString convertCharArray(const wchar_t *path)
+{
+ return QDir::fromNativeSeparators(QString::fromWCharArray(path));
+}
+
+QString QStandardPaths::writableLocation(StandardLocation type)
+{
+ QString result;
+
+ switch (type) {
+ case ConfigLocation: // same as DataLocation, on Windows
+ case DataLocation:
+ case GenericDataLocation: {
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ break;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ break;
+ ComPtr<IStorageFolder> settingsFolder;
+ if (FAILED(applicationData->get_LocalFolder(&settingsFolder)))
+ break;
+ ComPtr<IStorageItem> settingsFolderItem;
+ if (FAILED(settingsFolder.As(&settingsFolderItem)))
+ break;
+ HSTRING path;
+ if (FAILED(settingsFolderItem->get_Path(&path)))
+ break;
+ result = convertCharArray(WindowsGetStringRawBuffer(path, nullptr));
+ if (isTestModeEnabled())
+ result += QLatin1String("/qttest");
+ break;
+ }
+ case CacheLocation:
+ return writableLocation(DataLocation) + QLatin1String("/cache");
+
+ case GenericCacheLocation:
+ return writableLocation(GenericDataLocation) + QLatin1String("/cache");
+
+ case RuntimeLocation:
+ case HomeLocation:
+ result = QDir::homePath();
+ break;
+
+ case TempLocation:
+ result = QDir::tempPath();
+ break;
+ default:
+ Q_UNIMPLEMENTED();
+ }
+ return result;
+
+}
+
+QStringList QStandardPaths::standardLocations(StandardLocation type)
+{
+ return QStringList(writableLocation(type));
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index b3cb4e43f8..3cade0ed25 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -77,7 +77,7 @@ typedef int NativeFileHandle;
/*
* Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -151,18 +151,27 @@ static bool createFileFromTemplate(NativeFileHandle &file,
for (;;) {
// Atomically create file and obtain handle
#if defined(Q_OS_WIN)
+# ifndef Q_OS_WINRT
file = CreateFile((const wchar_t *)path.constData(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
+# else // !Q_OS_WINRT
+ file = CreateFile2((const wchar_t *)path.constData(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_NEW,
+ NULL);
+# endif // Q_OS_WINRT
if (file != INVALID_HANDLE_VALUE)
return true;
DWORD err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {
- DWORD attributes = GetFileAttributes((const wchar_t *)path.constData());
- if (attributes == INVALID_FILE_ATTRIBUTES) {
+ WIN32_FILE_ATTRIBUTE_DATA attributes;
+ if (!GetFileAttributesEx((const wchar_t *)path.constData(),
+ GetFileExInfoStandard, &attributes)
+ || attributes.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
// Potential write error (read-only parent directory, etc.).
error = QSystemError(err, QSystemError::NativeError);
return false;
@@ -336,7 +345,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
-#if !defined(Q_OS_WIN)
+#if !defined(Q_OS_WIN) || defined(Q_OS_WINRT)
d->closeFileHandle = true;
#endif
diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp
index 988d076025..bf2c07e0e0 100644
--- a/src/corelib/io/qurlidna.cpp
+++ b/src/corelib/io/qurlidna.cpp
@@ -73,7 +73,7 @@ inline bool operator<(const NameprepCaseFoldingEntry &one, uint other)
{ return one.uc < other; }
static const NameprepCaseFoldingEntry NameprepCaseFolding[] = {
-/* { 0x0041, { 0x0061, 0x0000, 0x0000, 0x0000 } },
+/* { 0x0041, { 0x0061, 0x0000, 0x0000, 0x0000 } },
{ 0x0042, { 0x0062, 0x0000, 0x0000, 0x0000 } },
{ 0x0043, { 0x0063, 0x0000, 0x0000, 0x0000 } },
{ 0x0044, { 0x0064, 0x0000, 0x0000, 0x0000 } },
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index 80fc0319fe..74a981b654 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qurl.h"
+#include "private/qutfcodec_p.h"
QT_BEGIN_NAMESPACE
@@ -232,110 +233,73 @@ static void ensureDetached(QString &result, ushort *&output, const ushort *begin
}
}
-// returns true if we performed an UTF-8 decoding
-static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *begin, const ushort *&input,
- const ushort *end, ushort decoded)
+namespace {
+struct QUrlUtf8Traits : public QUtf8BaseTraitsNoAscii
{
- int charsNeeded;
- uint min_uc;
- uint uc;
-
- if (decoded <= 0xC1) {
- // an UTF-8 first character must be at least 0xC0
- // however, all 0xC0 and 0xC1 first bytes can only produce overlong sequences
- return false;
- } else if (decoded < 0xe0) {
- charsNeeded = 2;
- min_uc = 0x80;
- uc = decoded & 0x1f;
- } else if (decoded < 0xf0) {
- charsNeeded = 3;
- min_uc = 0x800;
- uc = decoded & 0x0f;
- } else if (decoded < 0xf5) {
- charsNeeded = 4;
- min_uc = 0x10000;
- uc = decoded & 0x07;
- } else {
- // the last Unicode character is U+10FFFF
- // it's encoded in UTF-8 as "\xF4\x8F\xBF\xBF"
- // therefore, a byte higher than 0xF4 is not the UTF-8 first byte
- return false;
+ // override: our "bytes" are three percent-encoded UTF-16 characters
+ static void appendByte(ushort *&ptr, uchar b)
+ {
+ // b >= 0x80, by construction, so percent-encode
+ *ptr++ = '%';
+ *ptr++ = encodeNibble(b >> 4);
+ *ptr++ = encodeNibble(b & 0xf);
}
- // are there enough remaining?
- if (end - input < 3*charsNeeded)
- return false;
+ static uchar peekByte(const ushort *ptr, int n = 0)
+ {
+ // decodePercentEncoding returns ushort(-1) if it can't decode,
+ // which means we return 0xff, which is not a valid continuation byte.
+ // If ptr[i * 3] is not '%', we'll multiply by zero and return 0,
+ // also not a valid continuation byte (if it's '%', we multiply by 1).
+ return uchar(decodePercentEncoding(ptr + n * 3))
+ * uchar(ptr[n * 3] == '%');
+ }
- if (input[3] != '%')
- return false;
+ static qptrdiff availableBytes(const ushort *ptr, const ushort *end)
+ {
+ return (end - ptr) / 3;
+ }
- // first continuation character
- decoded = decodePercentEncoding(input + 3);
- if ((decoded & 0xc0) != 0x80)
- return false;
- uc <<= 6;
- uc |= decoded & 0x3f;
-
- if (charsNeeded > 2) {
- if (input[6] != '%')
- return false;
-
- // second continuation character
- decoded = decodePercentEncoding(input + 6);
- if ((decoded & 0xc0) != 0x80)
- return false;
- uc <<= 6;
- uc |= decoded & 0x3f;
-
- if (charsNeeded > 3) {
- if (input[9] != '%')
- return false;
-
- // third continuation character
- decoded = decodePercentEncoding(input + 9);
- if ((decoded & 0xc0) != 0x80)
- return false;
- uc <<= 6;
- uc |= decoded & 0x3f;
- }
+ static void advanceByte(const ushort *&ptr, int n = 1)
+ {
+ ptr += n * 3;
}
+};
+}
- // we've decoded something; safety-check it
- if (uc < min_uc)
- return false;
- if (QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint)
+// returns true if we performed an UTF-8 decoding
+static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *begin, const ushort *&input,
+ const ushort *end, ushort decoded)
+{
+ uint ucs4, *dst = &ucs4;
+ const ushort *src = input + 3;// skip the %XX that yielded \a decoded
+ int charsNeeded = QUtf8Functions::fromUtf8<QUrlUtf8Traits>(decoded, dst, src, end);
+ if (charsNeeded < 0)
return false;
- if (!QChar::requiresSurrogates(uc)) {
+ if (!QChar::requiresSurrogates(ucs4)) {
// UTF-8 decoded and no surrogates are required
// detach if necessary
- ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 1);
- *output++ = uc;
+ // possibilities are: 6 chars (%XX%XX) -> one char; 9 chars (%XX%XX%XX) -> one char
+ ensureDetached(result, output, begin, input, end, -3 * charsNeeded + 1);
+ *output++ = ucs4;
} else {
// UTF-8 decoded to something that requires a surrogate pair
- ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 2);
- *output++ = QChar::highSurrogate(uc);
- *output++ = QChar::lowSurrogate(uc);
+ // compressing from %XX%XX%XX%XX (12 chars) to two
+ ensureDetached(result, output, begin, input, end, -10);
+ *output++ = QChar::highSurrogate(ucs4);
+ *output++ = QChar::lowSurrogate(ucs4);
}
- input += charsNeeded * 3 - 1;
+
+ input = src - 1;
return true;
}
static void unicodeToEncodedUtf8(QString &result, ushort *&output, const ushort *begin,
const ushort *&input, const ushort *end, ushort decoded)
{
- uint uc = decoded;
- if (QChar::isHighSurrogate(uc)) {
- if (input < end && QChar::isLowSurrogate(input[1]))
- uc = QChar::surrogateToUcs4(uc, input[1]);
- }
-
- // note: we will encode bad UTF-16 to UTF-8
- // but they don't get decoded back
-
- // calculate the utf8 length
- int utf8len = uc >= 0x10000 ? 4 : uc >= 0x800 ? 3 : 2;
+ // calculate the utf8 length and ensure enough space is available
+ int utf8len = QChar::isHighSurrogate(decoded) ? 4 : decoded >= 0x800 ? 3 : 2;
// detach
if (!output) {
@@ -357,50 +321,32 @@ static void unicodeToEncodedUtf8(QString &result, ushort *&output, const ushort
}
}
- // write the sequence
- if (uc < 0x800) {
- // first of two bytes
- uchar c = 0xc0 | uchar(uc >> 6);
+ ++input;
+ int res = QUtf8Functions::toUtf8<QUrlUtf8Traits>(decoded, output, input, end);
+ --input;
+ if (res < 0) {
+ // bad surrogate pair sequence
+ // we will encode bad UTF-16 to UTF-8
+ // but they don't get decoded back
+
+ // first of three bytes
+ uchar c = 0xe0 | uchar(decoded >> 12);
*output++ = '%';
- *output++ = encodeNibble(c >> 4);
+ *output++ = 'E';
*output++ = encodeNibble(c & 0xf);
- } else {
- uchar c;
- if (uc > 0xFFFF) {
- // first two of four bytes
- c = 0xf0 | uchar(uc >> 18);
- *output++ = '%';
- *output++ = 'F';
- *output++ = encodeNibble(c & 0xf);
- // continuation byte
- c = 0x80 | (uchar(uc >> 12) & 0x3f);
- *output++ = '%';
- *output++ = encodeNibble(c >> 4);
- *output++ = encodeNibble(c & 0xf);
-
- // this was a surrogate pair
- ++input;
- } else {
- // first of three bytes
- c = 0xe0 | uchar(uc >> 12);
- *output++ = '%';
- *output++ = 'E';
- *output++ = encodeNibble(c & 0xf);
- }
+ // second byte
+ c = 0x80 | (uchar(decoded >> 6) & 0x3f);
+ *output++ = '%';
+ *output++ = encodeNibble(c >> 4);
+ *output++ = encodeNibble(c & 0xf);
- // continuation byte
- c = 0x80 | (uchar(uc >> 6) & 0x3f);
+ // third byte
+ c = 0x80 | (decoded & 0x3f);
*output++ = '%';
*output++ = encodeNibble(c >> 4);
*output++ = encodeNibble(c & 0xf);
}
-
- // continuation byte
- uchar c = 0x80 | (uc & 0x3f);
- *output++ = '%';
- *output++ = encodeNibble(c >> 4);
- *output++ = encodeNibble(c & 0xf);
}
static int recode(QString &result, const ushort *begin, const ushort *end, QUrl::ComponentFormattingOptions encoding,
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index fc9d191a90..df65aebcff 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -173,7 +173,8 @@ bool QWindowsPipeReader::canReadLine() const
\internal
Will be called whenever the read operation completes.
*/
-void QWindowsPipeReader::notified(DWORD numberOfBytesRead, DWORD errorCode, OVERLAPPED *notifiedOverlapped)
+void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
+ OVERLAPPED *notifiedOverlapped)
{
if (&overlapped != notifiedOverlapped)
return;
diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h
index ea3d3c271f..78ac8eb76d 100644
--- a/src/corelib/io/qwindowspipereader_p.h
+++ b/src/corelib/io/qwindowspipereader_p.h
@@ -94,7 +94,7 @@ Q_SIGNALS:
void pipeClosed();
private Q_SLOTS:
- void notified(DWORD numberOfBytesRead, DWORD errorCode, OVERLAPPED *notifiedOverlapped);
+ void notified(quint32 numberOfBytesRead, quint32 errorCode, OVERLAPPED *notifiedOverlapped);
private:
bool completeAsyncRead(DWORD bytesRead, DWORD errorCode);
diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp
index 1808081d01..daa8068734 100644
--- a/src/corelib/io/qwindowspipewriter.cpp
+++ b/src/corelib/io/qwindowspipewriter.cpp
@@ -114,7 +114,7 @@ void QWindowsPipeWriter::run()
if (quitNow) {
lock.unlock();
quitNow = false;
- break;
+ break;
}
QByteArray copy = data;
@@ -153,7 +153,7 @@ void QWindowsPipeWriter::run()
totalWritten += written;
#if defined QPIPEWRITER_DEBUG
qDebug("QWindowsPipeWriter::run() wrote %d %d/%d bytes",
- written, int(totalWritten), int(maxlen));
+ written, int(totalWritten), int(maxlen));
#endif
lock.lock();
data.remove(0, written);
diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp
index 914264e69e..33583afb78 100644
--- a/src/corelib/io/qwinoverlappedionotifier.cpp
+++ b/src/corelib/io/qwinoverlappedionotifier.cpp
@@ -43,8 +43,11 @@
#include <qdebug.h>
#include <qmutex.h>
#include <qpointer.h>
+#include <qqueue.h>
#include <qset.h>
#include <qthread.h>
+#include <qt_windows.h>
+#include <private/qobject_p.h>
QT_BEGIN_NAMESPACE
@@ -79,6 +82,46 @@ QT_BEGIN_NAMESPACE
\warning This class is only available on Windows.
*/
+struct IOResult
+{
+ IOResult(DWORD n = 0, DWORD e = 0, OVERLAPPED *p = 0)
+ : numberOfBytes(n), errorCode(e), overlapped(p)
+ {}
+
+ DWORD numberOfBytes;
+ DWORD errorCode;
+ OVERLAPPED *overlapped;
+};
+
+
+class QWinIoCompletionPort;
+
+class QWinOverlappedIoNotifierPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWinOverlappedIoNotifier)
+public:
+ QWinOverlappedIoNotifierPrivate()
+ : hHandle(INVALID_HANDLE_VALUE)
+ {
+ }
+
+ void notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped);
+ OVERLAPPED *_q_notified();
+
+ static QWinIoCompletionPort *iocp;
+ static HANDLE iocpInstanceLock;
+ static unsigned int iocpInstanceRefCount;
+ HANDLE hHandle;
+ HANDLE hSemaphore;
+ HANDLE hResultsMutex;
+ QQueue<IOResult> results;
+};
+
+QWinIoCompletionPort *QWinOverlappedIoNotifierPrivate::iocp = 0;
+HANDLE QWinOverlappedIoNotifierPrivate::iocpInstanceLock = CreateMutex(NULL, FALSE, NULL);
+unsigned int QWinOverlappedIoNotifierPrivate::iocpInstanceRefCount = 0;
+
+
class QWinIoCompletionPort : protected QThread
{
public:
@@ -109,11 +152,13 @@ public:
CloseHandle(hQueueDrainedEvent);
}
- void registerNotifier(QWinOverlappedIoNotifier *notifier)
+ void registerNotifier(QWinOverlappedIoNotifierPrivate *notifier)
{
- HANDLE hIOCP = CreateIoCompletionPort(notifier->hHandle, hPort, reinterpret_cast<ULONG_PTR>(notifier), 0);
+ const HANDLE hHandle = notifier->hHandle;
+ HANDLE hIOCP = CreateIoCompletionPort(hHandle, hPort,
+ reinterpret_cast<ULONG_PTR>(notifier), 0);
if (!hIOCP) {
- qErrnoWarning("Can't associate file handle %x with I/O completion port.", notifier->hHandle);
+ qErrnoWarning("Can't associate file handle %x with I/O completion port.", hHandle);
return;
}
mutex.lock();
@@ -123,7 +168,7 @@ public:
QThread::start();
}
- void unregisterNotifier(QWinOverlappedIoNotifier *notifier)
+ void unregisterNotifier(QWinOverlappedIoNotifierPrivate *notifier)
{
mutex.lock();
notifiers.remove(notifier);
@@ -176,7 +221,8 @@ protected:
continue;
}
- QWinOverlappedIoNotifier *notifier = reinterpret_cast<QWinOverlappedIoNotifier *>(pulCompletionKey);
+ QWinOverlappedIoNotifierPrivate *notifier
+ = reinterpret_cast<QWinOverlappedIoNotifierPrivate *>(pulCompletionKey);
mutex.lock();
if (notifiers.contains(notifier))
notifier->notify(dwBytesRead, errorCode, overlapped);
@@ -188,57 +234,62 @@ private:
const ULONG_PTR finishThreadKey;
const ULONG_PTR drainQueueKey;
HANDLE hPort;
- QSet<QWinOverlappedIoNotifier *> notifiers;
+ QSet<QWinOverlappedIoNotifierPrivate *> notifiers;
QMutex mutex;
QMutex drainQueueMutex;
HANDLE hQueueDrainedEvent;
};
-QWinIoCompletionPort *QWinOverlappedIoNotifier::iocp = 0;
-HANDLE QWinOverlappedIoNotifier::iocpInstanceLock = CreateMutex(NULL, FALSE, NULL);
-unsigned int QWinOverlappedIoNotifier::iocpInstanceRefCount = 0;
QWinOverlappedIoNotifier::QWinOverlappedIoNotifier(QObject *parent)
- : QObject(parent),
- hHandle(INVALID_HANDLE_VALUE)
+ : QObject(*new QWinOverlappedIoNotifierPrivate, parent)
{
- WaitForSingleObject(iocpInstanceLock, INFINITE);
- if (!iocp)
- iocp = new QWinIoCompletionPort;
- iocpInstanceRefCount++;
- ReleaseMutex(iocpInstanceLock);
-
- hSemaphore = CreateSemaphore(NULL, 0, 255, NULL);
- hResultsMutex = CreateMutex(NULL, FALSE, NULL);
- connect(this, &QWinOverlappedIoNotifier::_q_notify,
- this, &QWinOverlappedIoNotifier::_q_notified, Qt::QueuedConnection);
+ Q_D(QWinOverlappedIoNotifier);
+ WaitForSingleObject(d->iocpInstanceLock, INFINITE);
+ if (!d->iocp)
+ d->iocp = new QWinIoCompletionPort;
+ d->iocpInstanceRefCount++;
+ ReleaseMutex(d->iocpInstanceLock);
+
+ d->hSemaphore = CreateSemaphore(NULL, 0, 255, NULL);
+ d->hResultsMutex = CreateMutex(NULL, FALSE, NULL);
+ connect(this, SIGNAL(_q_notify()), this, SLOT(_q_notified()), Qt::QueuedConnection);
}
QWinOverlappedIoNotifier::~QWinOverlappedIoNotifier()
{
+ Q_D(QWinOverlappedIoNotifier);
setEnabled(false);
- CloseHandle(hResultsMutex);
- CloseHandle(hSemaphore);
+ CloseHandle(d->hResultsMutex);
+ CloseHandle(d->hSemaphore);
- WaitForSingleObject(iocpInstanceLock, INFINITE);
- if (!--iocpInstanceRefCount) {
- delete iocp;
- iocp = 0;
+ WaitForSingleObject(d->iocpInstanceLock, INFINITE);
+ if (!--d->iocpInstanceRefCount) {
+ delete d->iocp;
+ d->iocp = 0;
}
- ReleaseMutex(iocpInstanceLock);
+ ReleaseMutex(d->iocpInstanceLock);
}
-void QWinOverlappedIoNotifier::setHandle(HANDLE h)
+void QWinOverlappedIoNotifier::setHandle(Qt::HANDLE h)
{
- hHandle = h;
+ Q_D(QWinOverlappedIoNotifier);
+ d->hHandle = h;
+}
+
+Qt::HANDLE QWinOverlappedIoNotifier::handle() const
+{
+ Q_D(const QWinOverlappedIoNotifier);
+ return d->hHandle;
}
void QWinOverlappedIoNotifier::setEnabled(bool enabled)
{
+ Q_D(QWinOverlappedIoNotifier);
if (enabled)
- iocp->registerNotifier(this);
+ d->iocp->registerNotifier(d);
else
- iocp->unregisterNotifier(this);
+ d->iocp->unregisterNotifier(d);
}
/*!
@@ -249,18 +300,19 @@ void QWinOverlappedIoNotifier::setEnabled(bool enabled)
*/
bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped)
{
- if (!iocp->isRunning()) {
+ Q_D(QWinOverlappedIoNotifier);
+ if (!d->iocp->isRunning()) {
qWarning("Called QWinOverlappedIoNotifier::waitForNotified on inactive notifier.");
return false;
}
forever {
if (msecs == 0)
- iocp->drainQueue();
- DWORD result = WaitForSingleObject(hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs));
+ d->iocp->drainQueue();
+ DWORD result = WaitForSingleObject(d->hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs));
if (result == WAIT_OBJECT_0) {
- ReleaseSemaphore(hSemaphore, 1, NULL);
- if (_q_notified() == overlapped)
+ ReleaseSemaphore(d->hSemaphore, 1, NULL);
+ if (d->_q_notified() == overlapped)
return true;
continue;
} else if (result == WAIT_TIMEOUT) {
@@ -275,25 +327,30 @@ bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped
/*!
* Note: This function runs in the I/O completion port thread.
*/
-void QWinOverlappedIoNotifier::notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped)
+void QWinOverlappedIoNotifierPrivate::notify(DWORD numberOfBytes, DWORD errorCode,
+ OVERLAPPED *overlapped)
{
+ Q_Q(QWinOverlappedIoNotifier);
WaitForSingleObject(hResultsMutex, INFINITE);
results.enqueue(IOResult(numberOfBytes, errorCode, overlapped));
ReleaseMutex(hResultsMutex);
ReleaseSemaphore(hSemaphore, 1, NULL);
- emit _q_notify();
+ emit q->_q_notify();
}
-OVERLAPPED *QWinOverlappedIoNotifier::_q_notified()
+OVERLAPPED *QWinOverlappedIoNotifierPrivate::_q_notified()
{
+ Q_Q(QWinOverlappedIoNotifier);
if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0) {
WaitForSingleObject(hResultsMutex, INFINITE);
IOResult ioresult = results.dequeue();
ReleaseMutex(hResultsMutex);
- emit notified(ioresult.numberOfBytes, ioresult.errorCode, ioresult.overlapped);
+ emit q->notified(ioresult.numberOfBytes, ioresult.errorCode, ioresult.overlapped);
return ioresult.overlapped;
}
return 0;
}
QT_END_NAMESPACE
+
+#include "moc_qwinoverlappedionotifier_p.cpp"
diff --git a/src/corelib/io/qwinoverlappedionotifier_p.h b/src/corelib/io/qwinoverlappedionotifier_p.h
index 451bedf7cf..f90fd2e615 100644
--- a/src/corelib/io/qwinoverlappedionotifier_p.h
+++ b/src/corelib/io/qwinoverlappedionotifier_p.h
@@ -54,58 +54,35 @@
//
#include <qobject.h>
-#include <qt_windows.h>
-#include <qqueue.h>
+
+typedef struct _OVERLAPPED OVERLAPPED;
QT_BEGIN_NAMESPACE
-class QWinIoCompletionPort;
+class QWinOverlappedIoNotifierPrivate;
class Q_CORE_EXPORT QWinOverlappedIoNotifier : public QObject
{
Q_OBJECT
+ Q_DISABLE_COPY(QWinOverlappedIoNotifier)
+ Q_DECLARE_PRIVATE(QWinOverlappedIoNotifier)
+ Q_PRIVATE_SLOT(d_func(), OVERLAPPED *_q_notified())
+ friend class QWinIoCompletionPort;
public:
QWinOverlappedIoNotifier(QObject *parent = 0);
~QWinOverlappedIoNotifier();
- void setHandle(HANDLE h);
- HANDLE handle() const { return hHandle; }
+ void setHandle(Qt::HANDLE h);
+ Qt::HANDLE handle() const;
void setEnabled(bool enabled);
bool waitForNotified(int msecs, OVERLAPPED *overlapped);
Q_SIGNALS:
- void notified(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped);
+ void notified(quint32 numberOfBytes, quint32 errorCode, OVERLAPPED *overlapped);
+#if !defined(Q_QDOC)
void _q_notify();
-
-private Q_SLOTS:
- OVERLAPPED *_q_notified();
-
-private:
- void notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped);
-
-private:
- static QWinIoCompletionPort *iocp;
- static HANDLE iocpInstanceLock;
- static unsigned int iocpInstanceRefCount;
- HANDLE hHandle;
- HANDLE hSemaphore;
- HANDLE hResultsMutex;
-
- struct IOResult
- {
- IOResult(DWORD n = 0, DWORD e = 0, OVERLAPPED *p = 0)
- : numberOfBytes(n), errorCode(e), overlapped(p)
- {}
-
- DWORD numberOfBytes;
- DWORD errorCode;
- OVERLAPPED *overlapped;
- };
-
- QQueue<IOResult> results;
-
- friend class QWinIoCompletionPort;
+#endif
};
QT_END_NAMESPACE