summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/plugin/qlibrary.h3
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp23
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp91
3 files changed, 92 insertions, 25 deletions
diff --git a/src/corelib/plugin/qlibrary.h b/src/corelib/plugin/qlibrary.h
index c77533f..101df74 100644
--- a/src/corelib/plugin/qlibrary.h
+++ b/src/corelib/plugin/qlibrary.h
@@ -69,7 +69,8 @@ public:
enum LoadHint {
ResolveAllSymbolsHint = 0x01,
ExportExternalSymbolsHint = 0x02,
- LoadArchiveMemberHint = 0x04
+ LoadArchiveMemberHint = 0x04,
+ ImprovedSearchHeuristics = 0x08
};
Q_DECLARE_FLAGS(LoadHints, LoadHint)
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 1d0f322..74cf9a8 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -103,9 +103,9 @@ bool QLibraryPrivate::load_sys()
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(""));
+
+ QStringList suffixes;
+ QStringList prefixes;
if (pluginState != IsAPlugin) {
#if !defined(Q_OS_SYMBIAN)
prefixes << QLatin1String("lib");
@@ -187,6 +187,23 @@ bool QLibraryPrivate::load_sys()
}
#endif
#endif // QT_HPUX_LD
+ // If using the new search heuristics we do:
+ //
+ // If the filename is an absolute path then we want to try that first as it is most likely
+ // what the callee wants. If we have been given a non-absolute path then lets try the
+ // native library name first to avoid unnecessary calls to dlopen().
+ //
+ // otherwise:
+ //
+ // We use the old behaviour which is to always try the specified filename first
+ if ((loadHints & QLibrary::ImprovedSearchHeuristics) && !fsEntry.isAbsolute()) {
+ suffixes.append(QLatin1String(""));
+ prefixes.append(QLatin1String(""));
+ } else {
+ suffixes.prepend(QLatin1String(""));
+ prefixes.prepend(QLatin1String(""));
+ }
+
bool retry = true;
for(int prefix = 0; retry && !pHnd && prefix < prefixes.size(); prefix++) {
for(int suffix = 0; retry && !pHnd && suffix < suffixes.size(); suffix++) {
diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
index 0c450e3..2c09f6f 100644
--- a/src/corelib/plugin/qlibrary_win.cpp
+++ b/src/corelib/plugin/qlibrary_win.cpp
@@ -45,6 +45,7 @@
#include "qdir.h"
#include "qfileinfo.h"
#include "qdir.h"
+#include <private/qfilesystementry_p.h>
#if defined(QT_NO_LIBRARY) && defined(Q_OS_WIN)
#undef QT_NO_LIBRARY
@@ -59,46 +60,94 @@ extern QString qt_error_string(int code);
bool QLibraryPrivate::load_sys()
{
-#ifdef Q_OS_WINCE
- QString attempt = QFileInfo(fileName).absoluteFilePath();
-#else
- QString attempt = fileName;
-#endif
-
//avoid 'Bad Image' message box
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
- pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16());
- if (pluginState != IsAPlugin) {
+ // We make the following attempts at locating the library:
+ //
+ // WinCE
+ // if (loadHints & QLibrary::ImprovedSearchHeuristics)
+ // if (absolute)
+ // fileName
+ // fileName + ".dll"
+ // else
+ // fileName + ".dll"
+ // fileName
+ // QFileInfo(fileName).absoluteFilePath()
+ // else
+ // QFileInfo(fileName).absoluteFilePath();
+ // fileName
+ // fileName + ".dll"
+ //
+ // Windows
+ // if (loadHints & QLibrary::ImprovedSearchHeuristics)
+ // if (absolute)
+ // fileName
+ // fileName + ".dll"
+ // else
+ // fileName + ".dll"
+ // fileName
+ // else
+ // fileName
+ // fileName + ".dll"
+ //
+ // NB If it's a plugin we do not ever try the ".dll" extension
+ QStringList attempts;
+ QFileSystemEntry fsEntry(fileName);
+ if (loadHints & QLibrary::ImprovedSearchHeuristics) {
+ if (pluginState != IsAPlugin)
+ attempts.append(fileName + QLatin1String(".dll"));
+
+ // If the fileName is an absolute path we try that first, otherwise we
+ // use the system-specific suffix first
+ if (fsEntry.isAbsolute()) {
+ attempts.prepend(fileName);
+ } else {
+ attempts.append(fileName);
#if defined(Q_OS_WINCE)
- if (!pHnd && ::GetLastError() == ERROR_MOD_NOT_FOUND) {
- QString secondAttempt = fileName;
- pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(secondAttempt).utf16());
+ attempts.append(QFileInfo(fileName).absoluteFilePath());
+#endif
}
+ } else {
+#ifdef Q_OS_WINCE
+ attempts.append(QFileInfo(fileName).absoluteFilePath());
+#else
+ attempts.append(fileName);
+#endif
+ if (pluginState != IsAPlugin) {
+#if defined(Q_OS_WINCE)
+ attempts.append(fileName);
#endif
- if (!pHnd && ::GetLastError() == ERROR_MOD_NOT_FOUND) {
- attempt += QLatin1String(".dll");
- pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16());
+ attempts.append(fileName + QLatin1String(".dll"));
}
}
+ Q_FOREACH (const QString &attempt, attempts) {
+ pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16());
+
+ // If we have a handle or the last error is something other than "unable
+ // to find the module", then bail out
+ if (pHnd || ::GetLastError() != ERROR_MOD_NOT_FOUND)
+ break;
+ }
+
SetErrorMode(oldmode);
if (!pHnd) {
errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName).arg(qt_error_string());
- }
- if (pHnd) {
+ } else {
+ // Query the actual name of the library that was loaded
errorString.clear();
wchar_t buffer[MAX_PATH];
::GetModuleFileName(pHnd, buffer, MAX_PATH);
- attempt = QString::fromWCharArray(buffer);
- const QDir dir = QFileInfo(fileName).dir();
- const QString realfilename = attempt.mid(attempt.lastIndexOf(QLatin1Char('\\')) + 1);
+ QString moduleFileName = QString::fromWCharArray(buffer);
+ moduleFileName.remove(0, 1 + moduleFileName.lastIndexOf(QLatin1Char('\\')));
+ const QDir dir(fsEntry.path());
if (dir.path() == QLatin1String("."))
- qualifiedFileName = realfilename;
+ qualifiedFileName = moduleFileName;
else
- qualifiedFileName = dir.filePath(realfilename);
+ qualifiedFileName = dir.filePath(moduleFileName);
}
return (pHnd != 0);
}