Refactor plugin loading for WinRT

Specify the root directory to be the package root. Only plugins
inside the root can be opened (actually also only files). Furthermore
current defaults to the package root now, which in most cases is
identical to previous behavior.

When attempting to load a plugin the path can either be specified in
host format "C:/..." or as plugin absolute "/platforms/...". Check for
both, with preference of latter case, like when qt.conf is used with
/ being used as plugin path.

Change-Id: I7e3da293362488b62a3357c4882ebf5e048dcf95
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Andrew Knight <andrew.knight@digia.com>
Reviewed-by: Oliver Wolff <oliver.wolff@digia.com>
This commit is contained in:
Maurice Kalinowski 2013-11-01 16:16:15 +01:00 committed by The Qt Project
parent af0409d336
commit 2ff0746e97
5 changed files with 46 additions and 2 deletions

View File

@ -2141,7 +2141,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

View File

@ -77,11 +77,13 @@
# 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
@ -1180,6 +1182,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())
@ -1329,7 +1355,11 @@ QFileSystemEntry QFileSystemEngine::currentPath()
#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 // Q_OS_WINCE || Q_OS_WINRT

View File

@ -169,6 +169,12 @@ void QFileSystemEntry::resolveNativeFilePath() const
m_nativeFilePath = QDir::toNativeSeparators(m_filePath);
#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
}
}

View File

@ -525,6 +525,10 @@ void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
coreappdata()->app_libpaths = app_libpaths = new QStringList;
QString app_location = QCoreApplication::applicationFilePath();
app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
#ifdef Q_OS_WINRT
if (app_location.isEmpty())
app_location.append(QLatin1Char('/'));
#endif
app_location = QDir(app_location).canonicalPath();
if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
app_libpaths->append(app_location);

View File

@ -107,12 +107,16 @@ bool QLibraryPrivate::load_sys()
attempts.append(QFileInfo(fileName).absoluteFilePath());
#endif
}
#ifdef Q_OS_WINRT
if (fileName.startsWith(QLatin1Char('/')))
attempts.prepend(QDir::rootPath() + fileName);
#endif
Q_FOREACH (const QString &attempt, attempts) {
#ifndef Q_OS_WINRT
pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16());
#else // Q_OS_WINRT
QString path = QDir::toNativeSeparators(QDir::current().relativeFilePath(fileName));
QString path = QDir::toNativeSeparators(QDir::current().relativeFilePath(attempt));
pHnd = LoadPackagedLibrary((LPCWSTR)path.utf16(), 0);
if (pHnd)
qualifiedFileName = attempt;