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