Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsystemlibrary.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <QtCore/qvarlengtharray.h>
6#include <QtCore/qstringlist.h>
7#include <QtCore/qfileinfo.h>
8#include <QtCore/private/wcharhelpers_win_p.h>
9
10/*!
11
12 \internal
13 \class QSystemLibrary
14 \inmodule QtCore
15
16 The purpose of this class is to load only libraries that are located in
17 well-known and trusted locations on the filesystem. It does not suffer from
18 the security problem that QLibrary has, therefore it will never search in
19 the current directory.
20
21 The search order is the same as the order in DLL Safe search mode Windows,
22 except that we don't search:
23 * The current directory
24 * The 16-bit system directory. (normally \c{c:\windows\system})
25 * The Windows directory. (normally \c{c:\windows})
26
27 This means that the effective search order is:
28 1. Application path.
29 2. System libraries path.
30 3. Trying all paths inside the PATH environment variable.
31
32 Note, when onlySystemDirectory is true it will skip 1) and 3).
33
34 DLL Safe search mode is documented in the "Dynamic-Link Library Search
35 Order" document on MSDN.
36*/
37
38QT_BEGIN_NAMESPACE
39
40using namespace Qt::StringLiterals;
41
42#if !defined(QT_BOOTSTRAPPED)
43extern QString qAppFileName();
44#endif
45
47{
48 static const QString result = []() -> QString {
49 QVarLengthArray<wchar_t, MAX_PATH> fullPath = {};
50 UINT retLen = ::GetSystemDirectoryW(fullPath.data(), MAX_PATH);
51 if (retLen > MAX_PATH) {
52 fullPath.resize(retLen);
53 retLen = ::GetSystemDirectoryW(fullPath.data(), retLen);
54 }
55 // in some rare cases retLen might be 0
56 return QString::fromWCharArray(fullPath.constData(), int(retLen));
57 }();
58 return result;
59}
60
61HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirectory /* = true */)
62{
63 if (onlySystemDirectory)
64 return ::LoadLibraryExW(libraryName, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
65
66 QStringList searchOrder;
67
68#if !defined(QT_BOOTSTRAPPED)
69 searchOrder << QFileInfo(qAppFileName()).path();
70#endif
71 searchOrder << qSystemDirectory();
72
73 const QString PATH(QLatin1StringView(qgetenv("PATH")));
74 searchOrder << PATH.split(u';', Qt::SkipEmptyParts);
75
76 const QString fileName = QString::fromWCharArray(libraryName);
77
78 // Start looking in the order specified
79 for (int i = 0; i < searchOrder.count(); ++i) {
80 QString fullPathAttempt = searchOrder.at(i);
81 if (!fullPathAttempt.endsWith(u'\\')) {
82 fullPathAttempt.append(u'\\');
83 }
84 fullPathAttempt.append(fileName);
85 HINSTANCE inst = ::LoadLibrary(qt_castToWchar(fullPathAttempt));
86 if (inst != nullptr)
87 return inst;
88 }
89 return nullptr;
90}
91
92QT_END_NAMESPACE
QString qAppFileName()
static QString qSystemDirectory()