Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qnetworkproxy_win.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
4#include "qnetworkproxy.h"
5
6#ifndef QT_NO_NETWORKPROXY
7
8#include <qmutex.h>
9#include <qstringlist.h>
10#include <qregularexpression.h>
11#include <qurl.h>
12#include <qnetworkinterface.h>
13#include <qdebug.h>
14#include <qvarlengtharray.h>
15#include <qhash.h>
16
17#include <string.h>
18#include <qt_windows.h>
19#include <lmcons.h>
20#include <winhttp.h>
21
23
24using namespace Qt::StringLiterals;
25
27{
28 wchar_t userName[UNLEN + 1] = L"";
29 DWORD size = UNLEN;
30 if (GetUserNameW(userName, &size)) {
31 SID_NAME_USE type = SidTypeUser;
32 DWORD sidSize = 0;
33 DWORD domainSize = 0;
34 // first call is to get the correct size
35 bool bRet = LookupAccountNameW(NULL, userName, NULL, &sidSize, NULL, &domainSize, &type);
36 if (bRet == FALSE && ERROR_INSUFFICIENT_BUFFER != GetLastError())
37 return false;
38 QVarLengthArray<BYTE, 68> buff(sidSize);
39 QVarLengthArray<wchar_t, MAX_PATH> domainName(domainSize);
40 // second call to LookupAccountNameW actually gets the SID
41 // both the pointer to the buffer and the pointer to the domain name should not be NULL
42 if (LookupAccountNameW(NULL, userName, buff.data(), &sidSize, domainName.data(), &domainSize, &type))
43 return type != SidTypeUser; //returns true if the current user is not a user
44 }
45 return false;
46}
47
49{
51 qsizetype start = 0;
53 while (true) {
54 qsizetype space = source.indexOf(u' ', start);
55 qsizetype semicolon = source.indexOf(u';', start);
56 end = space;
57 if (semicolon != -1 && (end == -1 || semicolon < end))
58 end = semicolon;
59
60 if (end == -1) {
61 if (start != source.length())
62 list.append(source.mid(start));
63 return list;
64 }
65 if (start != end)
67 start = end + 1;
68 }
69 return list;
70}
71
72static bool isBypassed(const QString &host, const QStringList &bypassList)
73{
74 if (host.isEmpty())
75 return false;
76
77 bool isSimple = !host.contains(u'.') && !host.contains(u':');
78
79 QHostAddress ipAddress;
80 bool isIpAddress = ipAddress.setAddress(host);
81
82 // always exclude loopback
83 if (isIpAddress && ipAddress.isLoopback())
84 return true;
85
86 // does it match the list of exclusions?
87 for (const QString &entry : bypassList) {
88 if (entry == "<local>"_L1) {
89 if (isSimple)
90 return true;
91 if (isIpAddress) {
92 //exclude all local subnets
93 const auto ifaces = QNetworkInterface::allInterfaces();
94 for (const QNetworkInterface &iface : ifaces) {
95 const auto netaddrs = iface.addressEntries();
96 for (const QNetworkAddressEntry &netaddr : netaddrs) {
97 if (ipAddress.isInSubnet(netaddr.ip(), netaddr.prefixLength())) {
98 return true;
99 }
100 }
101 }
102 }
103 }
104 if (isIpAddress && ipAddress.isInSubnet(QHostAddress::parseSubnet(entry))) {
105 return true; // excluded
106 } else {
107 // do wildcard matching
109 if (rx.match(host).hasMatch())
110 return true;
111 }
112 }
113
114 // host was not excluded
115 return false;
116}
117
118static QList<QNetworkProxy> filterProxyListByCapabilities(const QList<QNetworkProxy> &proxyList, const QNetworkProxyQuery &query)
119{
120 QNetworkProxy::Capabilities requiredCaps;
121 switch (query.queryType()) {
124 break;
127 break;
130 break;
133 break;
136 break;
137 default:
138 return proxyList;
139 break;
140 }
141 QList<QNetworkProxy> result;
142 for (const QNetworkProxy &proxy : proxyList) {
143 if (proxy.capabilities() & requiredCaps)
144 result.append(proxy);
145 }
146 return result;
147}
148
149static QList<QNetworkProxy> removeDuplicateProxies(const QList<QNetworkProxy> &proxyList)
150{
151 QList<QNetworkProxy> result;
152 for (const QNetworkProxy &proxy : proxyList) {
153 bool append = true;
154 for (int i=0; i < result.count(); i++) {
155 if (proxy.hostName() == result.at(i).hostName()
156 && proxy.port() == result.at(i).port()) {
157 append = false;
158 // HttpProxy trumps FtpCachingProxy or HttpCachingProxy on the same host/port
160 result[i] = proxy;
161 }
162 }
163 if (append)
164 result.append(proxy);
165 }
166 return result;
167}
168
169static QList<QNetworkProxy> parseServerList(const QNetworkProxyQuery &query, const QStringList &proxyList)
170{
171 // Reference documentation from Microsoft:
172 // http://msdn.microsoft.com/en-us/library/aa383912(VS.85).aspx
173 //
174 // According to the website, the proxy server list is
175 // one or more of the space- or semicolon-separated strings in the format:
176 // ([<scheme>=][<scheme>"://"]<server>[":"<port>])
177 // The first scheme relates to the protocol tag
178 // The second scheme, if present, overrides the proxy type
179
180 QList<QNetworkProxy> result;
181 QHash<QString, QNetworkProxy> taggedProxies;
182 const QString requiredTag = query.protocolTag();
183 // windows tags are only for clients
184 bool checkTags = !requiredTag.isEmpty()
185 && query.queryType() != QNetworkProxyQuery::TcpServer
186 && query.queryType() != QNetworkProxyQuery::SctpServer;
187 for (const QString &entry : proxyList) {
188 qsizetype server = 0;
189
191 quint16 port = 8080;
192
193 qsizetype pos = entry.indexOf(u'=');
194 QStringView scheme;
195 QStringView protocolTag;
196 if (pos != -1) {
197 scheme = protocolTag = QStringView{entry}.left(pos);
198 server = pos + 1;
199 }
200 pos = entry.indexOf("://"_L1, server);
201 if (pos != -1) {
202 scheme = QStringView{entry}.mid(server, pos - server);
203 server = pos + 3;
204 }
205
206 if (!scheme.isEmpty()) {
207 if (scheme == "http"_L1 || scheme == "https"_L1) {
208 // no-op
209 // defaults are above
210 } else if (scheme == "socks"_L1 || scheme == "socks5"_L1) {
211 proxyType = QNetworkProxy::Socks5Proxy;
212 port = 1080;
213 } else if (scheme == "ftp"_L1) {
215 port = 2121;
216 } else {
217 // unknown proxy type
218 continue;
219 }
220 }
221
222 pos = entry.indexOf(u':', server);
223 if (pos != -1) {
224 bool ok;
225 uint value = QStringView{entry}.mid(pos + 1).toUInt(&ok);
226 if (!ok || value > 65535)
227 continue; // invalid port number
228
229 port = value;
230 } else {
231 pos = entry.length();
232 }
233
234 result << QNetworkProxy(proxyType, entry.mid(server, pos - server), port);
235 if (!protocolTag.isEmpty())
236 taggedProxies.insert(protocolTag.toString(), result.constLast());
237 }
238
239 if (checkTags && taggedProxies.contains(requiredTag)) {
240 if (query.queryType() == QNetworkProxyQuery::UrlRequest) {
241 result.clear();
242 result.append(taggedProxies.value(requiredTag));
243 return result;
244 } else {
245 result.prepend(taggedProxies.value(requiredTag));
246 }
247 }
248 if (!checkTags || requiredTag != "http"_L1) {
249 // if there are different http proxies for http and https, prefer the https one (more likely to be capable of CONNECT)
250 QNetworkProxy httpProxy = taggedProxies.value("http"_L1);
251 QNetworkProxy httpsProxy = taggedProxies.value("http"_L1);
252 if (httpProxy != httpsProxy && httpProxy.type() == QNetworkProxy::HttpProxy && httpsProxy.type() == QNetworkProxy::HttpProxy) {
253 for (int i = 0; i < result.count(); i++) {
254 if (httpProxy == result.at(i))
256 }
257 }
258 }
261}
262
263namespace {
264class QRegistryWatcher {
265 Q_DISABLE_COPY_MOVE(QRegistryWatcher)
266public:
267 QRegistryWatcher() = default;
268
269 void addLocation(HKEY hive, const QString& path)
270 {
271 HKEY openedKey;
272 if (RegOpenKeyEx(hive, reinterpret_cast<const wchar_t*>(path.utf16()), 0, KEY_READ, &openedKey) != ERROR_SUCCESS)
273 return;
274
275 const DWORD filter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES |
276 REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY;
277
278 // Watch the registry key for a change of value.
279 HANDLE handle = CreateEvent(NULL, true, false, NULL);
280 if (RegNotifyChangeKeyValue(openedKey, true, filter, handle, true) != ERROR_SUCCESS) {
281 CloseHandle(handle);
282 return;
283 }
284 m_watchEvents.append(handle);
285 m_registryHandles.append(openedKey);
286 }
287
288 bool hasChanged() const {
289 return !isEmpty() &&
290 WaitForMultipleObjects(m_watchEvents.size(), m_watchEvents.data(), false, 0) < WAIT_OBJECT_0 + m_watchEvents.size();
291 }
292
293 bool isEmpty() const {
294 return m_watchEvents.isEmpty();
295 }
296
297 void clear() {
298 for (HANDLE event : std::as_const(m_watchEvents))
299 CloseHandle(event);
300 for (HKEY key : std::as_const(m_registryHandles))
301 RegCloseKey(key);
302
303 m_watchEvents.clear();
304 m_registryHandles.clear();
305 }
306
307 ~QRegistryWatcher() {
308 clear();
309 }
310
311private:
312 QList<HANDLE> m_watchEvents;
313 QList<HKEY> m_registryHandles;
314};
315} // namespace
316
318{
319 Q_DISABLE_COPY_MOVE(QWindowsSystemProxy)
320public:
323 void init();
324 void reset();
325
327
328 HINTERNET hHttpSession;
329 WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions;
330
334 QList<QNetworkProxy> defaultResult;
335 QRegistryWatcher proxySettingsWatcher;
339};
340
342
344 : hHttpSession(0), initialized(false), functional(false), isAutoConfig(false)
345{
346 defaultResult << QNetworkProxy::NoProxy;
347}
348
350{
351 if (hHttpSession)
352 WinHttpCloseHandle(hHttpSession);
353}
354
356{
358 proxyServerList.clear();
359 proxyBypass.clear();
362 functional = false;
363 isAutoConfig = false;
364}
365
367{
368 bool proxySettingsChanged = false;
369 proxySettingsChanged = proxySettingsWatcher.hasChanged();
370
371 if (initialized && !proxySettingsChanged)
372 return;
373 initialized = true;
374
375 reset();
376
377 proxySettingsWatcher.clear(); // needs reset to trigger a new detection
378 proxySettingsWatcher.addLocation(HKEY_CURRENT_USER, QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"));
379 proxySettingsWatcher.addLocation(HKEY_LOCAL_MACHINE, QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"));
380 proxySettingsWatcher.addLocation(HKEY_LOCAL_MACHINE, QStringLiteral("Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"));
381
382 // Try to obtain the Internet Explorer configuration.
383 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieProxyConfig;
384 const bool hasIEConfig = WinHttpGetIEProxyConfigForCurrentUser(&ieProxyConfig);
385 if (hasIEConfig) {
386 if (ieProxyConfig.lpszAutoConfigUrl) {
387 autoConfigUrl = QString::fromWCharArray(ieProxyConfig.lpszAutoConfigUrl);
388 GlobalFree(ieProxyConfig.lpszAutoConfigUrl);
389 }
390 if (ieProxyConfig.lpszProxy) {
391 // http://msdn.microsoft.com/en-us/library/aa384250%28VS.85%29.aspx speaks only about a "proxy URL",
392 // not multiple URLs. However we tested this and it can return multiple URLs. So we use splitSpaceSemicolon
393 // on it.
395 GlobalFree(ieProxyConfig.lpszProxy);
396 }
397 if (ieProxyConfig.lpszProxyBypass) {
398 proxyBypass = splitSpaceSemicolon(QString::fromWCharArray(ieProxyConfig.lpszProxyBypass));
399 GlobalFree(ieProxyConfig.lpszProxyBypass);
400 }
401 }
402
403 if (!hasIEConfig ||
404 (currentProcessIsService() && proxyServerList.isEmpty() && proxyBypass.isEmpty())) {
405 // no user configuration
406 // attempt to get the default configuration instead
407 // that config will serve as default if WPAD fails
408 WINHTTP_PROXY_INFO proxyInfo;
409 if (WinHttpGetDefaultProxyConfiguration(&proxyInfo) &&
410 proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY) {
411 // we got information from the registry
412 // overwrite the IE configuration, if any
413
414 proxyBypass = splitSpaceSemicolon(QString::fromWCharArray(proxyInfo.lpszProxyBypass));
416 }
417
418 if (proxyInfo.lpszProxy)
419 GlobalFree(proxyInfo.lpszProxy);
420 if (proxyInfo.lpszProxyBypass)
421 GlobalFree(proxyInfo.lpszProxyBypass);
422 }
423
424 hHttpSession = NULL;
425 if (ieProxyConfig.fAutoDetect || !autoConfigUrl.isEmpty()) {
426 // open the handle and obtain the options
427 hHttpSession = WinHttpOpen(L"Qt System Proxy access/1.0",
428 WINHTTP_ACCESS_TYPE_NO_PROXY,
429 WINHTTP_NO_PROXY_NAME,
430 WINHTTP_NO_PROXY_BYPASS,
431 0);
432 if (!hHttpSession)
433 return;
434
435 isAutoConfig = true;
436 memset(&autoProxyOptions, 0, sizeof autoProxyOptions);
437 autoProxyOptions.fAutoLogonIfChallenged = false;
438 //Although it is possible to specify dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL
439 //this has poor performance (WPAD is attempted for every url, taking 2.5 seconds per interface,
440 //before the configured pac file is used)
441 if (ieProxyConfig.fAutoDetect) {
442 autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
443 autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP |
444 WINHTTP_AUTO_DETECT_TYPE_DNS_A;
445 } else {
446 autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
447 autoProxyOptions.lpszAutoConfigUrl = reinterpret_cast<LPCWSTR>(autoConfigUrl.utf16());
448 }
449 }
450
452}
453
455{
456 QWindowsSystemProxy *sp = systemProxy();
457 if (!sp)
458 return QList<QNetworkProxy>() << QNetworkProxy();
459
460 QMutexLocker locker(&sp->mutex);
461 sp->init();
462 if (!sp->functional)
463 return sp->defaultResult;
464
465 if (sp->isAutoConfig) {
466 WINHTTP_PROXY_INFO proxyInfo;
467
468 // try to get the proxy config for the URL
469 QUrl url = query.url();
470 // url could be empty, e.g. from QNetworkProxy::applicationProxy(), that's fine,
471 // we'll still ask for the proxy.
472 // But for a file url, we know we don't need one.
473 if (url.scheme() == "file"_L1 || url.scheme() == "qrc"_L1)
474 return sp->defaultResult;
475 if (query.queryType() != QNetworkProxyQuery::UrlRequest) {
476 // change the scheme to https, maybe it'll work
477 url.setScheme("https"_L1);
478 }
479
480 QString urlQueryString = url.toString();
481 if (urlQueryString.size() > 2083) {
482 // calls to WinHttpGetProxyForUrl with urls longer than 2083 characters
483 // fail with error code ERROR_INVALID_PARAMETER(87), so we truncate it
484 qWarning("Proxy query URL too long for windows API, try with truncated URL");
485 urlQueryString = url.toString().left(2083);
486 }
487
488 bool getProxySucceeded = WinHttpGetProxyForUrl(sp->hHttpSession,
489 reinterpret_cast<LPCWSTR>(urlQueryString.utf16()),
490 &sp->autoProxyOptions,
491 &proxyInfo);
492 DWORD getProxyError = GetLastError();
493
494 if (!getProxySucceeded
495 && (ERROR_WINHTTP_AUTODETECTION_FAILED == getProxyError)) {
496 // WPAD failed
497 if (sp->autoConfigUrl.isEmpty()) {
498 //No config file could be retrieved on the network.
499 //Don't search for it next time again.
500 sp->isAutoConfig = false;
501 } else {
502 //pac file URL is specified as well, try using that
503 sp->autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
504 sp->autoProxyOptions.lpszAutoConfigUrl =
505 reinterpret_cast<LPCWSTR>(sp->autoConfigUrl.utf16());
506 getProxySucceeded = WinHttpGetProxyForUrl(sp->hHttpSession,
507 reinterpret_cast<LPCWSTR>(urlQueryString.utf16()),
508 &sp->autoProxyOptions,
509 &proxyInfo);
510 getProxyError = GetLastError();
511 }
512 }
513
514 if (!getProxySucceeded
515 && (ERROR_WINHTTP_LOGIN_FAILURE == getProxyError)) {
516 // We first tried without AutoLogon, because this might prevent caching the result.
517 // But now we've to enable it (http://msdn.microsoft.com/en-us/library/aa383153%28v=VS.85%29.aspx)
518 sp->autoProxyOptions.fAutoLogonIfChallenged = TRUE;
519 getProxySucceeded = WinHttpGetProxyForUrl(sp->hHttpSession,
520 reinterpret_cast<LPCWSTR>(urlQueryString.utf16()),
521 &sp->autoProxyOptions,
522 &proxyInfo);
523 getProxyError = GetLastError();
524 }
525
526 if (!getProxySucceeded
527 && (ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT == getProxyError)) {
528 // PAC file url is not connectable, or server returned error (e.g. http 404)
529 //Don't search for it next time again.
530 sp->isAutoConfig = false;
531 }
532
533 if (getProxySucceeded) {
534 // yes, we got a config for this URL
535 QString proxyBypass = QString::fromWCharArray(proxyInfo.lpszProxyBypass);
536 QStringList proxyServerList = splitSpaceSemicolon(QString::fromWCharArray(proxyInfo.lpszProxy));
537 if (proxyInfo.lpszProxy)
538 GlobalFree(proxyInfo.lpszProxy);
539 if (proxyInfo.lpszProxyBypass)
540 GlobalFree(proxyInfo.lpszProxyBypass);
541
542 if (proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY)
543 return sp->defaultResult; //i.e. the PAC file result was "DIRECT"
544 if (isBypassed(query.peerHostName(), splitSpaceSemicolon(proxyBypass)))
545 return sp->defaultResult;
546 return parseServerList(query, proxyServerList);
547 }
548
549 // GetProxyForUrl failed, fall back to static configuration
550 }
551
552 // static configuration
553 if (isBypassed(query.peerHostName(), sp->proxyBypass))
554 return sp->defaultResult;
555
556 QList<QNetworkProxy> result = parseServerList(query, sp->proxyServerList);
557 // In some cases, this was empty. See SF task 00062670
558 if (result.isEmpty())
559 return sp->defaultResult;
560
561 return result;
562}
563
565
566#endif
The QHostAddress class provides an IP address.
void setAddress(quint32 ip4Addr)
Set the IPv4 address specified by ip4Addr.
static QPair< QHostAddress, int > parseSubnet(const QString &subnet)
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
Definition qmutex.h:281
The QNetworkAddressEntry class stores one IP address supported by a network interface,...
The QNetworkInterface class provides a listing of the host's IP addresses and network interfaces.
static QList< QNetworkInterface > allInterfaces()
Returns a listing of all the network interfaces found on the host machine.
static QList< QNetworkProxy > systemProxyForQuery(const QNetworkProxyQuery &query=QNetworkProxyQuery())
This function takes the query request, query, examines the details of the type of socket or request a...
The QNetworkProxyQuery class is used to query the proxy settings for a socket.
The QNetworkProxy class provides a network layer proxy.
ProxyType
This enum describes the types of network proxying provided in Qt.
Capabilities capabilities() const
QNetworkProxy::ProxyType type() const
Returns the proxy type for this instance.
void setType(QNetworkProxy::ProxyType type)
Sets the proxy type for this instance to be type.
QString hostName() const
Returns the host name of the proxy host.
quint16 port() const
Returns the port of the proxy host.
static QRegularExpression fromWildcard(QStringView pattern, Qt::CaseSensitivity cs=Qt::CaseInsensitive, WildcardConversionOptions options=DefaultWildcardConversion)
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
constexpr QStringView left(qsizetype n) const noexcept
QString toString() const
Returns a deep copy of this string view's data as a QString.
Definition qstring.h:1121
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
const ushort * utf16() const
Returns the QString as a '\0\'-terminated array of unsigned shorts.
Definition qstring.cpp:6995
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1226
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1369
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
Definition qstring.h:1309
\inmodule QtCore
Definition qurl.h:94
QString url(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2817
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
Definition qurl.cpp:1967
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2831
QList< QNetworkProxy > defaultResult
WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions
QRegistryWatcher proxySettingsWatcher
b clear()
list append(new Employee("Blackpool", "Stephen"))
Combined button and popup list for selecting options.
void * HANDLE
@ CaseInsensitive
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage return DBusPendingCall DBusPendingCall return DBusPendingCall return dbus_int32_t return DBusServer * server
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
EGLOutputPortEXT port
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
static QStringList splitSpaceSemicolon(const QString &source)
static QList< QNetworkProxy > removeDuplicateProxies(const QList< QNetworkProxy > &proxyList)
static bool isBypassed(const QString &host, const QStringList &bypassList)
static QList< QNetworkProxy > filterProxyListByCapabilities(const QList< QNetworkProxy > &proxyList, const QNetworkProxyQuery &query)
static QList< QNetworkProxy > parseServerList(const QNetworkProxyQuery &query, const QStringList &proxyList)
static bool currentProcessIsService()
GLuint64 GLenum void * handle
GLuint64 key
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLuint end
GLenum type
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLuint start
GLsizei GLsizei GLchar * source
struct _cl_event * event
GLenum query
GLuint entry
GLsizei const GLchar *const * path
GLuint64EXT * result
[6]
#define QStringLiteral(str)
#define sp
unsigned short quint16
Definition qtypes.h:48
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
QList< int > list
[14]
QUrl url("example.com")
[constructor-url-reference]
p rx()++
QNetworkProxy proxy
[0]
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:962