diff options
Diffstat (limited to 'src/network/kernel/qnetworkproxy_win.cpp')
-rw-r--r-- | src/network/kernel/qnetworkproxy_win.cpp | 100 |
1 files changed, 91 insertions, 9 deletions
diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp index f2176d664d..9e571bfe7f 100644 --- a/src/network/kernel/qnetworkproxy_win.cpp +++ b/src/network/kernel/qnetworkproxy_win.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtNetwork module of the Qt Toolkit. ** @@ -10,9 +10,9 @@ ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser @@ -23,8 +23,8 @@ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ @@ -352,12 +352,66 @@ static QList<QNetworkProxy> parseServerList(const QNetworkProxyQuery &query, con return removeDuplicateProxies(result); } +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) +namespace { +class QRegistryWatcher { +public: + void addLocation(HKEY hive, const QString& path) + { + HKEY openedKey; + if (RegOpenKeyEx(hive, reinterpret_cast<const wchar_t*>(path.utf16()), 0, KEY_READ, &openedKey) != ERROR_SUCCESS) + return; + + const DWORD filter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | + REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; + + // Watch the registry key for a change of value. + HANDLE handle = CreateEvent(NULL, true, false, NULL); + if (RegNotifyChangeKeyValue(openedKey, true, filter, handle, true) != ERROR_SUCCESS) { + CloseHandle(handle); + return; + } + m_watchEvents.append(handle); + m_registryHandles.append(openedKey); + } + + bool hasChanged() const { + return !isEmpty() && + WaitForMultipleObjects(m_watchEvents.size(), m_watchEvents.data(), false, 0) < WAIT_OBJECT_0 + m_watchEvents.size(); + } + + bool isEmpty() const { + return m_watchEvents.isEmpty(); + } + + void clear() { + foreach (HANDLE event, m_watchEvents) + CloseHandle(event); + foreach (HKEY key, m_registryHandles) + RegCloseKey(key); + + m_watchEvents.clear(); + m_registryHandles.clear(); + } + + ~QRegistryWatcher() { + clear(); + } + +private: + QVector<HANDLE> m_watchEvents; + QVector<HKEY> m_registryHandles; +}; +} // namespace +#endif // !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) + class QWindowsSystemProxy { public: QWindowsSystemProxy(); ~QWindowsSystemProxy(); void init(); + void reset(); QMutex mutex; @@ -368,7 +422,9 @@ public: QStringList proxyServerList; QStringList proxyBypass; QList<QNetworkProxy> defaultResult; - +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) + QRegistryWatcher proxySettingsWatcher; +#endif bool initialized; bool functional; bool isAutoConfig; @@ -388,16 +444,42 @@ QWindowsSystemProxy::~QWindowsSystemProxy() ptrWinHttpCloseHandle(hHttpSession); } +void QWindowsSystemProxy::reset() +{ + autoConfigUrl.clear(); + proxyServerList.clear(); + proxyBypass.clear(); + defaultResult.clear(); + defaultResult << QNetworkProxy::NoProxy; + functional = false; + isAutoConfig = false; +} + void QWindowsSystemProxy::init() { - if (initialized) + bool proxySettingsChanged = false; +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) + proxySettingsChanged = proxySettingsWatcher.hasChanged(); +#endif + + if (initialized && !proxySettingsChanged) return; initialized = true; + reset(); + #ifdef Q_OS_WINCE // Windows CE does not have any of the following API return; #else + +#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) + proxySettingsWatcher.clear(); // needs reset to trigger a new detection + proxySettingsWatcher.addLocation(HKEY_CURRENT_USER, QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")); + proxySettingsWatcher.addLocation(HKEY_LOCAL_MACHINE, QStringLiteral("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")); + proxySettingsWatcher.addLocation(HKEY_LOCAL_MACHINE, QStringLiteral("Software\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings")); +#endif + // load the winhttp.dll library QSystemLibrary lib(L"winhttp"); if (!lib.load()) |