summaryrefslogtreecommitdiffstats
path: root/src/corelib/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/plugin')
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp13
-rw-r--r--src/corelib/plugin/qlibrary.cpp95
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp27
-rw-r--r--src/corelib/plugin/qpluginloader.cpp56
-rw-r--r--src/corelib/plugin/quuid.cpp2
5 files changed, 162 insertions, 31 deletions
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 487ce3a..69dfa13 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -64,6 +64,7 @@ class QFactoryLoaderPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QFactoryLoader)
public:
QFactoryLoaderPrivate(){}
+ ~QFactoryLoaderPrivate();
mutable QMutex mutex;
QByteArray iid;
QList<QLibraryPrivate*> libraryList;
@@ -76,6 +77,12 @@ public:
void unloadPath(const QString &path);
};
+QFactoryLoaderPrivate::~QFactoryLoaderPrivate()
+{
+ for (int i = 0; i < libraryList.count(); ++i)
+ libraryList.at(i)->release();
+}
+
QFactoryLoader::QFactoryLoader(const char *iid,
const QString &suffix,
Qt::CaseSensitivity cs)
@@ -89,8 +96,8 @@ QFactoryLoader::QFactoryLoader(const char *iid,
QMutexLocker locker(qt_factoryloader_mutex());
- qt_factory_loaders()->append(this);
update();
+ qt_factory_loaders()->append(this);
}
@@ -197,10 +204,6 @@ void QFactoryLoader::update()
QFactoryLoader::~QFactoryLoader()
{
- Q_D(QFactoryLoader);
- for (int i = 0; i < d->libraryList.count(); ++i)
- d->libraryList.at(i)->release();
-
QMutexLocker locker(qt_factoryloader_mutex());
qt_factory_loaders()->removeAll(this);
}
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index f784622..5cf6513 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -98,10 +98,10 @@ Q_GLOBAL_STATIC(QMutex, qt_library_mutex)
Unix), unless the file name has an absolute path. If the file
cannot be found, QLibrary tries the name with different
platform-specific file suffixes, like ".so" on Unix, ".dylib" on
- the Mac, or ".dll" on Windows. This makes it possible to specify
- shared libraries that are only identified by their basename (i.e.
- without their suffix), so the same code will work on different
- operating systems.
+ the Mac, or ".dll" on Windows and Symbian. This makes it possible
+ to specify shared libraries that are only identified by their
+ basename (i.e. without their suffix), so the same code will work
+ on different operating systems.
The most important functions are load() to dynamically load the
library file, isLoaded() to check whether loading was successful,
@@ -120,6 +120,11 @@ Q_GLOBAL_STATIC(QMutex, qt_library_mutex)
linking", which is done by the link step in the build process when
linking an executable against a library.
+ Note: In Symbian resolving symbols using their names is supported
+ only if the library is built as STDDLL. Otherwise ordinals must
+ be used. Also, in Symbian the path of the library is ignored and
+ system default library location is always used.
+
The following code snippet loads a library, resolves the symbol
"mysymbol", and calls the function if everything succeeded. If
something goes wrong, e.g. the library file does not exist or the
@@ -288,7 +293,7 @@ static bool qt_parse_pattern(const char *s, uint *version, bool *debug, QByteArr
}
#endif // QT_NO_PLUGIN_CHECK
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(QT_NO_PLUGIN_CHECK)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN) && !defined(QT_NO_PLUGIN_CHECK)
#if defined(Q_OS_FREEBSD) || defined(Q_OS_LINUX)
# define USE_MMAP
@@ -361,7 +366,7 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB
char *filedata = 0;
ulong fdlen = 0;
-#ifdef USE_MMAP
+# ifdef USE_MMAP
char *mapaddr = 0;
size_t maplen = file.size();
mapaddr = (char *) mmap(mapaddr, maplen, PROT_READ, MAP_PRIVATE, file.handle(), 0);
@@ -378,14 +383,14 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB
lib->errorString = QLibrary::tr("Could not mmap '%1': %2")
.arg(library)
.arg(qt_error_string());
-#endif // USE_MMAP
+# endif // USE_MMAP
// try reading the data into memory instead
data = file.readAll();
filedata = data.data();
fdlen = data.size();
-#ifdef USE_MMAP
+# ifdef USE_MMAP
}
-#endif // USE_MMAP
+# endif // USE_MMAP
// verify that the pattern is present in the plugin
const char pattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA";
@@ -398,7 +403,7 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB
if (!ret && lib)
lib->errorString = QLibrary::tr("Plugin verification data mismatch in '%1'").arg(library);
-#ifdef USE_MMAP
+# ifdef USE_MMAP
if (mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0) {
if (qt_debug_component())
qWarning("munmap: %s", qPrintable(qt_error_string(errno)));
@@ -407,13 +412,13 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB
.arg(library)
.arg( qt_error_string() );
}
-#endif // USE_MMAP
+# endif // USE_MMAP
file.close();
return ret;
}
-#endif // Q_OS_UNIX && !Q_OS_MAC && !defined(QT_NO_PLUGIN_CHECK)
+#endif // Q_OS_UNIX && !Q_OS_MAC && !defined(Q_OS_SYMBIAN) && !defined(QT_NO_PLUGIN_CHECK)
typedef QMap<QString, QLibraryPrivate*> LibraryMap;
@@ -509,6 +514,14 @@ bool QLibraryPrivate::loadPlugin()
}
if (load()) {
instance = (QtPluginInstanceFunction)resolve("qt_plugin_instance");
+#if defined(Q_OS_SYMBIAN)
+ if (!instance) {
+ // If resolving with function name failed (i.e. not STDDLL),
+ // try resolving using known ordinal, which for
+ // qt_plugin_instance function is always "2".
+ instance = (QtPluginInstanceFunction)resolve("2");
+ }
+#endif
return instance;
}
return false;
@@ -533,6 +546,10 @@ bool QLibrary::isLibrary(const QString &fileName)
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
return fileName.endsWith(QLatin1String(".dll"));
+#elif defined(Q_OS_SYMBIAN)
+ // Plugin stubs are also considered libraries in Symbian.
+ return (fileName.endsWith(QLatin1String(".dll")) ||
+ fileName.endsWith(QLatin1String(".qtplugin")));
#else
QString completeSuffix = QFileInfo(fileName).completeSuffix();
if (completeSuffix.isEmpty())
@@ -628,7 +645,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
key = reg.at(2).toLatin1();
success = qt_version != 0;
} else {
-#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_SYMBIAN)
if (!pHnd) {
// use unix shortcut to avoid loading the library
success = qt_unix_query(fileName, &qt_version, &debug, &key, this);
@@ -643,6 +660,10 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
#ifdef Q_OS_WIN
hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, DONT_RESOLVE_DLL_REFERENCES);
#else
+# if defined(Q_OS_SYMBIAN)
+ //Guard against accidentally trying to load non-plugin libraries by making sure the stub exists
+ if (fileinfo.exists())
+# endif
temporary_load = load_sys();
#endif
}
@@ -661,8 +682,17 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
#endif
: (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
#else
- QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction =
- (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
+ QtPluginQueryVerificationDataFunction qtPluginQueryVerificationDataFunction = NULL;
+# if defined(Q_OS_SYMBIAN)
+ if (temporary_load) {
+ qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
+ // If resolving with function name failed (i.e. not STDDLL), try resolving using known ordinal
+ if (!qtPluginQueryVerificationDataFunction)
+ qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("1");
+ }
+# else
+ qtPluginQueryVerificationDataFunction = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_verification_data");
+# endif
#endif
if (!qtPluginQueryVerificationDataFunction
@@ -832,6 +862,8 @@ QLibrary::QLibrary(QObject *parent)
QLibrary will automatically look for the file with the appropriate
suffix in accordance with the platform, e.g. ".so" on Unix,
".dylib" on Mac OS X, and ".dll" on Windows. (See \l{fileName}.)
+
+ Note: In Symbian the path portion of the \a fileName is ignored.
*/
QLibrary::QLibrary(const QString& fileName, QObject *parent)
:QObject(parent), d(0), did_load(false)
@@ -843,13 +875,15 @@ QLibrary::QLibrary(const QString& fileName, QObject *parent)
/*!
Constructs a library object with the given \a parent that will
load the library specified by \a fileName and major version number \a verNum.
- Currently, the version number is ignored on Windows.
+ Currently, the version number is ignored on Windows and Symbian.
We recommend omitting the file's suffix in \a fileName, since
QLibrary will automatically look for the file with the appropriate
suffix in accordance with the platform, e.g. ".so" on Unix,
".dylib" on Mac OS X, and ".dll" on Windows. (See \l{fileName}.)
- */
+
+ Note: In Symbian the path portion of the \a fileName is ignored.
+*/
QLibrary::QLibrary(const QString& fileName, int verNum, QObject *parent)
:QObject(parent), d(0), did_load(false)
{
@@ -859,12 +893,14 @@ QLibrary::QLibrary(const QString& fileName, int verNum, QObject *parent)
/*!
Constructs a library object with the given \a parent that will
load the library specified by \a fileName and full version number \a version.
- Currently, the version number is ignored on Windows.
+ Currently, the version number is ignored on Windows and Symbian.
We recommend omitting the file's suffix in \a fileName, since
QLibrary will automatically look for the file with the appropriate
suffix in accordance with the platform, e.g. ".so" on Unix,
".dylib" on Mac OS X, and ".dll" on Windows. (See \l{fileName}.)
+
+ Note: In Symbian the path portion of the \a fileName is ignored.
*/
QLibrary::QLibrary(const QString& fileName, const QString &version, QObject *parent)
:QObject(parent), d(0), did_load(false)
@@ -906,6 +942,8 @@ QLibrary::~QLibrary()
platforms, fileName() will return "libGL.so". If the file name was
originally passed as "/usr/lib/libGL", fileName() will return
"/usr/lib/libGL.so".
+
+ Note: In Symbian the path portion of the \a fileName is ignored.
*/
void QLibrary::setFileName(const QString &fileName)
@@ -933,7 +971,10 @@ QString QLibrary::fileName() const
Sets the fileName property and major version number to \a fileName
and \a versionNumber respectively.
- The \a versionNumber is ignored on Windows.
+ The \a versionNumber is ignored on Windows and Symbian.
+
+ Note: In Symbian the path portion of the \a fileName is ignored.
+
\sa setFileName()
*/
void QLibrary::setFileNameAndVersion(const QString &fileName, int verNum)
@@ -954,7 +995,10 @@ void QLibrary::setFileNameAndVersion(const QString &fileName, int verNum)
Sets the fileName property and full version number to \a fileName
and \a version respectively.
- The \a version parameter is ignored on Windows.
+ The \a version parameter is ignored on Windows and Symbian.
+
+ Note: In Symbian the path portion of the \a fileName is ignored.
+
\sa setFileName()
*/
void QLibrary::setFileNameAndVersion(const QString &fileName, const QString &version)
@@ -990,6 +1034,8 @@ void QLibrary::setFileNameAndVersion(const QString &fileName, const QString &ver
\snippet doc/src/snippets/code/src_corelib_plugin_qlibrary.cpp 4
+ Note: In Symbian resolving with symbol names works only if the loaded
+ library was built as STDDLL. Otherwise, the ordinals must be used.
*/
void *QLibrary::resolve(const char *symbol)
{
@@ -1009,6 +1055,9 @@ void *QLibrary::resolve(const char *symbol)
The function returns 0 if the symbol could not be resolved or if
the library could not be loaded.
+ Note: In Symbian resolving with symbol names works only if the loaded
+ library was built as STDDLL. Otherwise, the ordinals must be used.
+
\sa resolve()
*/
void *QLibrary::resolve(const QString &fileName, const char *symbol)
@@ -1029,6 +1078,9 @@ void *QLibrary::resolve(const QString &fileName, const char *symbol)
The function returns 0 if the symbol could not be resolved or if
the library could not be loaded.
+ Note: In Symbian resolving with symbol names works only if the loaded
+ library was built as STDDLL. Otherwise, the ordinals must be used.
+
\sa resolve()
*/
void *QLibrary::resolve(const QString &fileName, int verNum, const char *symbol)
@@ -1050,6 +1102,9 @@ void *QLibrary::resolve(const QString &fileName, int verNum, const char *symbol)
The function returns 0 if the symbol could not be resolved or if
the library could not be loaded.
+ Note: In Symbian resolving with symbol names works only if the loaded
+ library was built as STDDLL. Otherwise, the ordinals must be used.
+
\sa resolve()
*/
void *QLibrary::resolve(const QString &fileName, const QString &version, const char *symbol)
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 35c1073..62e6464 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -81,18 +81,31 @@ bool QLibraryPrivate::load_sys()
QString attempt;
#if !defined(Q_OS_VXWORKS)
QFileInfo fi(fileName);
+
+#if defined(Q_OS_SYMBIAN)
+ QString path; // In Symbian, always resolve with just the filename
+ QString name;
+
+ // Replace possible ".qtplugin" suffix with ".dll"
+ if (fi.suffix() == QLatin1String("qtplugin"))
+ name = fi.completeBaseName() + QLatin1String(".dll");
+ else
+ name = fi.fileName();
+#else
QString path = fi.path();
QString name = fi.fileName();
if (path == QLatin1String(".") && !fileName.startsWith(path))
path.clear();
else
path += QLatin1Char('/');
-
+#endif
// The first filename we want to attempt to load is the filename as the callee specified.
// Thus, the first attempt we do must be with an empty prefix and empty suffix.
QStringList suffixes(QLatin1String("")), prefixes(QLatin1String(""));
if (pluginState != IsAPlugin) {
+#if !defined(Q_OS_SYMBIAN)
prefixes << QLatin1String("lib");
+#endif
#if defined(Q_OS_HPUX)
// according to
// http://docs.hp.com/en/B2355-90968/linkerdifferencesiapa.htm
@@ -120,6 +133,9 @@ bool QLibraryPrivate::load_sys()
}
#elif defined(Q_OS_AIX)
suffixes << ".a";
+
+#elif defined(Q_OS_SYMBIAN)
+ suffixes << QLatin1String(".dll");
#else
if (!fullVersion.isEmpty()) {
suffixes << QString::fromLatin1(".so.%1").arg(fullVersion);
@@ -157,7 +173,7 @@ bool QLibraryPrivate::load_sys()
else {
#if defined(Q_OS_MAC)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4)
-#endif
+#endif
dlFlags |= RTLD_LOCAL;
}
#endif
@@ -188,6 +204,12 @@ bool QLibraryPrivate::load_sys()
#else
pHnd = dlopen(QFile::encodeName(attempt), dlFlags);
#endif
+
+#if defined(Q_OS_SYMBIAN)
+ // Never try again in symbian, dlopen already handles the library search logic,
+ // and there is only one possible suffix.
+ retry = false;
+#else
if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
// We only want to continue if dlopen failed due to that the shared library did not exist.
// However, we are only able to apply this check for absolute filenames (since they are
@@ -195,6 +217,7 @@ bool QLibraryPrivate::load_sys()
// This is all because dlerror is flawed and cannot tell us the reason why it failed.
retry = false;
}
+#endif
}
}
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index 521063c..971cc2b 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -46,6 +46,7 @@
#include <qfileinfo.h>
#include "qlibrary_p.h"
#include "qdebug.h"
+#include "qdir.h"
#ifndef QT_NO_LIBRARY
@@ -116,6 +117,16 @@ QT_BEGIN_NAMESPACE
link to plugins statically. You can use QLibrary if you need to
load dynamic libraries in a statically linked application.
+ \note In Symbian the plugin stub files must be used whenever a
+ path to plugin is needed. For the purposes of loading plugins,
+ the stubs can be considered to have the same name as the actual
+ plugin binary. In practice they have ".qtplugin" extension
+ instead of ".dll", but this difference is handled transparently
+ by QPluginLoader and QLibrary to avoid need for Symbian specific
+ plugin handling in most Qt applications. Plugin stubs are needed
+ because Symbian Platform Security denies all access to the directory
+ where the actual plugin binaries are located.
+
\sa QLibrary, {Plug & Paint Example}
*/
@@ -136,6 +147,8 @@ QPluginLoader::QPluginLoader(QObject *parent)
Unix, - \c .dylib on Mac OS X, and \c .dll on Windows. The suffix
can be verified with QLibrary::isLibrary().
+ Note: In Symbian the \a fileName must point to plugin stub file.
+
\sa setFileName()
*/
QPluginLoader::QPluginLoader(const QString &fileName, QObject *parent)
@@ -170,7 +183,7 @@ QPluginLoader::~QPluginLoader()
The root component, returned by this function, is not deleted when
the QPluginLoader is destroyed. If you want to ensure that the root
component is deleted, you should call unload() as soon you don't
- need to access the core component anymore. When the library is
+ need to access the core component anymore. When the library is
finally unloaded, the root component will automatically be deleted.
The component object is a QObject. Use qobject_cast() to access
@@ -221,9 +234,9 @@ bool QPluginLoader::load()
call will fail, and unloading will only happen when every instance
has called unload().
- Don't try to delete the root component. Instead rely on
+ Don't try to delete the root component. Instead rely on
that unload() will automatically delete it when needed.
-
+
\sa instance(), load()
*/
bool QPluginLoader::unload()
@@ -261,6 +274,8 @@ bool QPluginLoader::isLoaded() const
By default, this property contains an empty string.
+ Note: In Symbian the \a fileName must point to plugin stub file.
+
\sa load()
*/
void QPluginLoader::setFileName(const QString &fileName)
@@ -273,7 +288,42 @@ void QPluginLoader::setFileName(const QString &fileName)
d = 0;
did_load = false;
}
+
+#if defined(Q_OS_SYMBIAN)
+ // In Symbian we actually look for plugin stub, so modify the filename
+ // to make canonicalFilePath find the file, if .dll is specified.
+ QFileInfo fi(fileName);
+
+ if (fi.suffix() == QLatin1String("dll")) {
+ QString stubName = fileName;
+ stubName.chop(3);
+ stubName += QLatin1String("qtplugin");
+ fi = QFileInfo(stubName);
+ }
+
+ QString fn = fi.canonicalFilePath();
+ // If not found directly, check also all the available drives
+ if (!fn.length()) {
+ QString stubPath(fi.fileName().length() ? fi.absoluteFilePath() : QString());
+ if (stubPath.length() > 1) {
+ if (stubPath.at(1).toAscii() == ':')
+ stubPath.remove(0,2);
+ QFileInfoList driveList(QDir::drives());
+ foreach(const QFileInfo& drive, driveList) {
+ QString testFilePath(drive.absolutePath() + stubPath);
+ testFilePath = QDir::cleanPath(testFilePath);
+ if (QFile::exists(testFilePath)) {
+ fn = testFilePath;
+ break;
+ }
+ }
+ }
+ }
+
+#else
QString fn = QFileInfo(fileName).canonicalFilePath();
+#endif
+
d = QLibraryPrivate::findOrCreate(fn);
d->loadHints = lh;
if (fn.isEmpty())
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index 400f42d..7e0e242 100644
--- a/src/corelib/plugin/quuid.cpp
+++ b/src/corelib/plugin/quuid.cpp
@@ -557,7 +557,7 @@ bool QUuid::operator>(const QUuid &other) const
\sa variant(), version()
*/
-#if defined(Q_OS_WIN32)
+#if defined(Q_OS_WIN32) && ! defined(Q_CC_MWERKS)
QT_BEGIN_INCLUDE_NAMESPACE
#include <objbase.h> // For CoCreateGuid