summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMaurice Kalinowski <maurice.kalinowski@theqtcompany.com>2015-12-11 13:42:28 +0100
committerMaurice Kalinowski <maurice.kalinowski@theqtcompany.com>2016-01-21 05:53:17 +0000
commitf05c597ae506ea6163394dbb6b70ecc77fae3b3c (patch)
tree02a3b3644bd9c0657aed855d7d348d527cdbefce /src
parentf4502fbaf0d31d08bf08f1685f1d7b30735b72b4 (diff)
winrt: msvc2015: refactor file handling
msvc2015 reintroduced a couple of functions from the win32 API towards WinRT. Enable usage of those and simplify the file system engine. Furthermore update the autotests. Change-Id: I9eafffba0ddfd05917c184c4a6b9e166f86d71d9 Reviewed-by: Oliver Wolff <oliver.wolff@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qdir.cpp11
-rw-r--r--src/corelib/io/qfileinfo.cpp2
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp33
-rw-r--r--src/corelib/io/qfilesystementry.cpp10
-rw-r--r--src/corelib/io/qfilesystemiterator_win.cpp3
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp2
6 files changed, 49 insertions, 12 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 4d2b36632f..2c2bdd579e 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -152,7 +152,11 @@ inline void QDirPrivate::setPath(const QString &path)
if (p.endsWith(QLatin1Char('/'))
&& p.length() > 1
#if defined(Q_OS_WIN)
+# if defined (Q_OS_WINRT)
+ && (!(p.toLower() == QDir::rootPath().toLower()))
+# else
&& (!(p.length() == 3 && p.at(1).unicode() == ':' && p.at(0).isLetter()))
+# endif
#endif
) {
p.truncate(p.length() - 1);
@@ -885,6 +889,9 @@ bool QDir::cd(const QString &dirName)
#if defined (Q_OS_UNIX)
//After cleanPath() if path is "/.." or starts with "/../" it means trying to cd above root.
if (newPath.startsWith(QLatin1String("/../")) || newPath == QLatin1String("/.."))
+#elif defined (Q_OS_WINRT)
+ const QString rootPath = QDir::rootPath();
+ if (newPath.size() < rootPath.size() && rootPath.startsWith(newPath))
#else
/*
cleanPath() already took care of replacing '\' with '/'.
@@ -2187,7 +2194,11 @@ QString QDir::cleanPath(const QString &path)
// Strip away last slash except for root directories
if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) {
#if defined (Q_OS_WIN)
+# if defined(Q_OS_WINRT)
+ if (!((ret.length() == 3 || ret.length() == QDir::rootPath().length()) && ret.at(1) == QLatin1Char(':')))
+# else
if (!(ret.length() == 3 && ret.at(1) == QLatin1Char(':')))
+# endif
#endif
ret.chop(1);
}
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 51b39b1114..dd194594c9 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -1095,7 +1095,7 @@ bool QFileInfo::isRoot() const
return true;
if (d->fileEngine == 0) {
if (d->fileEntry.isRoot()) {
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
//the path is a drive root, but the drive may not exist
//for backward compatibility, return true only if the drive exists
if (!d->cache_enabled || !d->metaData.hasFlags(QFileSystemMetaData::ExistsAttribute))
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 379095a83d..f1a6019094 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -78,6 +78,11 @@ using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Storage;
using namespace ABI::Windows::ApplicationModel;
+
+#if _MSC_VER < 1900
+#define Q_OS_WINRT_WIN81
+#endif
+
#endif // Q_OS_WINRT
#ifndef SPI_GETPLATFORMTYPE
@@ -522,7 +527,7 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
{
// can be //server or //server/share
QString absPath;
-#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT_WIN81)
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);
@@ -532,6 +537,16 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
}
if (retLen != 0)
absPath = QString::fromWCharArray(buf.data(), retLen);
+# if defined(Q_OS_WINRT)
+ // Win32 returns eg C:/ as root directory with a trailing /.
+ // WinRT returns the sandbox root without /.
+ // Also C:/../.. returns C:/ on Win32, while for WinRT it steps outside the package
+ // and goes beyond package root. Hence force the engine to stay inside
+ // the package.
+ const QString rootPath = QDir::toNativeSeparators(QDir::rootPath());
+ if (absPath.size() < rootPath.size() && rootPath.startsWith(absPath))
+ absPath = rootPath;
+# endif // Q_OS_WINRT
#elif !defined(Q_OS_WINCE)
if (QDir::isRelativePath(path))
absPath = QDir::toNativeSeparators(QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + path));
@@ -569,7 +584,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
ret = entry.filePath();
#endif
} else {
-#ifndef Q_OS_WINRT
+#ifndef Q_OS_WINRT_WIN81
ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + entry.filePath());
#else
// Some WinRT APIs do not support absolute paths (due to sandboxing).
@@ -1218,8 +1233,8 @@ QString QFileSystemEngine::rootPath()
if (FAILED(item->get_Path(finalWinPath.GetAddressOf())))
return ret;
- ret = QDir::fromNativeSeparators(QString::fromWCharArray(finalWinPath.GetRawBuffer(nullptr)));
-
+ const QString qtWinPath = QDir::fromNativeSeparators(QString::fromWCharArray(finalWinPath.GetRawBuffer(nullptr)));
+ ret = qtWinPath.endsWith(QLatin1Char('/')) ? qtWinPath : qtWinPath + QLatin1Char('/');
#else
QString ret = QString::fromLatin1(qgetenv("SystemDrive"));
if (ret.isEmpty())
@@ -1337,7 +1352,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
if(!(meta.exists() && meta.isDirectory()))
return false;
-#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT_WIN81)
//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;
@@ -1350,7 +1365,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
QFileSystemEntry QFileSystemEngine::currentPath()
{
QString ret;
-#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT_WIN81)
DWORD size = 0;
wchar_t currentName[PATH_MAX];
size = ::GetCurrentDirectory(PATH_MAX, currentName);
@@ -1366,17 +1381,17 @@ QFileSystemEntry QFileSystemEngine::currentPath()
}
if (ret.length() >= 2 && ret[1] == QLatin1Char(':'))
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
-#else // !Q_OS_WINCE && !Q_OS_WINRT
+#else // !Q_OS_WINCE && !Q_OS_WINRT_WIN81
//TODO - a race condition exists when using currentPath / setCurrentPath from multiple threads
if (qfsPrivateCurrentDir.isEmpty())
-#ifndef Q_OS_WINRT
+#ifndef Q_OS_WINRT_WIN81
qfsPrivateCurrentDir = QCoreApplication::applicationDirPath();
#else
qfsPrivateCurrentDir = QDir::rootPath();
#endif
ret = qfsPrivateCurrentDir;
-#endif // Q_OS_WINCE || Q_OS_WINRT
+#endif // Q_OS_WINCE || Q_OS_WINRT_WIN81
return QFileSystemEntry(ret, QFileSystemEntry::FromNativePath());
}
diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp
index 709970e3ac..c590d81f7a 100644
--- a/src/corelib/io/qfilesystementry.cpp
+++ b/src/corelib/io/qfilesystementry.cpp
@@ -166,6 +166,12 @@ void QFileSystemEntry::resolveNativeFilePath() const
m_nativeFilePath.remove(0,1);
if (m_nativeFilePath.isEmpty())
m_nativeFilePath.append(QLatin1Char('.'));
+ // WinRT/MSVC2015 allows a maximum of 256 characters for a filepath
+ // unless //?/ is prepended which extends the rule to have a maximum
+ // of 256 characters in the filename plus the preprending path
+#if _MSC_VER >= 1900
+ m_nativeFilePath.prepend("\\\\?\\");
+#endif
#endif
}
}
@@ -283,9 +289,13 @@ bool QFileSystemEntry::isAbsolute() const
bool QFileSystemEntry::isDriveRoot() const
{
resolveFilePath();
+#ifndef Q_OS_WINRT
return (m_filePath.length() == 3
&& m_filePath.at(0).isLetter() && m_filePath.at(1) == QLatin1Char(':')
&& m_filePath.at(2) == QLatin1Char('/'));
+#else // !Q_OS_WINRT
+ return m_filePath == QDir::rootPath();
+#endif // !Q_OS_WINRT
}
#endif
diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp
index 6351a3559d..d7fed87222 100644
--- a/src/corelib/io/qfilesystemiterator_win.cpp
+++ b/src/corelib/io/qfilesystemiterator_win.cpp
@@ -67,7 +67,8 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
if (!nativePath.endsWith(QLatin1Char('\\')))
nativePath.append(QLatin1Char('\\'));
nativePath.append(QLatin1Char('*'));
-#ifdef Q_OS_WINRT
+ // In MSVC2015+ case we prepend //?/ for longer file-name support
+#if defined(Q_OS_WINRT) && _MSC_VER < 1900
if (nativePath.startsWith(QLatin1Char('\\')))
nativePath.remove(0, 1);
#endif
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index cfd50955a6..886d526fb1 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -1037,7 +1037,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
offsetHi, offsetLo, size + extra);
#else
LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access,
- (ULONG64(offsetHi) << 32) + offsetLo, size);
+ (ULONG64(offsetHi) << 32) + offsetLo, size + extra);
#endif
if (mapAddress) {
uchar *address = extra + static_cast<uchar*>(mapAddress);