summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qfilesystemengine_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qfilesystemengine_win.cpp')
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 826a023d3d..0829bbc6e8 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -84,6 +84,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
@@ -528,7 +533,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);
@@ -538,6 +543,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));
@@ -575,7 +590,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).
@@ -1224,8 +1239,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())
@@ -1343,7 +1358,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;
@@ -1356,7 +1371,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);
@@ -1372,17 +1387,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());
}