diff options
Diffstat (limited to 'src/network/kernel/qnetconmonitor_win.cpp')
-rw-r--r-- | src/network/kernel/qnetconmonitor_win.cpp | 121 |
1 files changed, 42 insertions, 79 deletions
diff --git a/src/network/kernel/qnetconmonitor_win.cpp b/src/network/kernel/qnetconmonitor_win.cpp index 81e253ff81..bf6aff1e46 100644 --- a/src/network/kernel/qnetconmonitor_win.cpp +++ b/src/network/kernel/qnetconmonitor_win.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNetwork module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qnetconmonitor_p.h" @@ -44,13 +8,15 @@ #include <QtCore/quuid.h> #include <QtCore/qmetaobject.h> +#include <QtCore/private/qfunctions_win_p.h> +#include <QtCore/private/qsystemerror_p.h> + #include <QtNetwork/qnetworkinterface.h> #include <objbase.h> #include <netlistmgr.h> #include <wrl/client.h> #include <wrl/wrappers/corewrappers.h> -#include <comdef.h> #include <iphlpapi.h> #include <algorithm> @@ -62,12 +28,6 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcNetMon, "qt.network.monitor"); namespace { -QString errorStringFromHResult(HRESULT hr) -{ - _com_error error(hr); - return QString::fromWCharArray(error.ErrorMessage()); -} - template<typename T> bool QueryInterfaceImpl(IUnknown *from, REFIID riid, void **ppvObject) { @@ -160,6 +120,8 @@ public: void setConnectivity(NLM_CONNECTIVITY newConnectivity); private: + QComHelper comHelper; + ComPtr<QNetworkConnectionEvents> connectionEvents; // We can assume we have access to internet/subnet when this class is created because // connection has already been established to the peer: @@ -172,7 +134,6 @@ private: bool sameSubnet = false; bool isLinkLocal = false; bool monitoring = false; - bool comInitFailed = false; bool remoteIsIPv6 = false; }; @@ -182,8 +143,8 @@ QNetworkConnectionEvents::QNetworkConnectionEvents(QNetworkConnectionMonitorPriv auto hr = CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_INPROC_SERVER, IID_INetworkListManager, &networkListManager); if (FAILED(hr)) { - qCWarning(lcNetMon) << "Could not get a NetworkListManager instance:" - << errorStringFromHResult(hr); + qCDebug(lcNetMon) << "Could not get a NetworkListManager instance:" + << QSystemError::windowsComString(hr); return; } @@ -194,8 +155,8 @@ QNetworkConnectionEvents::QNetworkConnectionEvents(QNetworkConnectionMonitorPriv &connectionPoint); } if (FAILED(hr)) { - qCWarning(lcNetMon) << "Failed to get connection point for network events:" - << errorStringFromHResult(hr); + qCDebug(lcNetMon) << "Failed to get connection point for network events:" + << QSystemError::windowsComString(hr); } } @@ -206,27 +167,33 @@ QNetworkConnectionEvents::~QNetworkConnectionEvents() ComPtr<INetworkConnection> QNetworkConnectionEvents::getNetworkConnectionFromAdapterGuid(QUuid guid) { + if (!networkListManager) { + qCDebug(lcNetMon) << "Failed to enumerate network connections:" + << "NetworkListManager was not instantiated"; + return nullptr; + } + ComPtr<IEnumNetworkConnections> connections; auto hr = networkListManager->GetNetworkConnections(connections.GetAddressOf()); if (FAILED(hr)) { - qCWarning(lcNetMon) << "Failed to enumerate network connections:" - << errorStringFromHResult(hr); + qCDebug(lcNetMon) << "Failed to enumerate network connections:" + << QSystemError::windowsComString(hr); return nullptr; } ComPtr<INetworkConnection> connection = nullptr; do { hr = connections->Next(1, connection.GetAddressOf(), nullptr); if (FAILED(hr)) { - qCWarning(lcNetMon) << "Failed to get next network connection in enumeration:" - << errorStringFromHResult(hr); + qCDebug(lcNetMon) << "Failed to get next network connection in enumeration:" + << QSystemError::windowsComString(hr); break; } if (connection) { GUID adapterId; hr = connection->GetAdapterId(&adapterId); if (FAILED(hr)) { - qCWarning(lcNetMon) << "Failed to get adapter ID from network connection:" - << errorStringFromHResult(hr); + qCDebug(lcNetMon) << "Failed to get adapter ID from network connection:" + << QSystemError::windowsComString(hr); continue; } if (guid == adapterId) @@ -276,22 +243,23 @@ bool QNetworkConnectionEvents::setTarget(const QNetworkInterface &iface) NET_LUID luid; if (ConvertInterfaceIndexToLuid(iface.index(), &luid) != NO_ERROR) { - qCWarning(lcNetMon, "Could not get the LUID for the interface."); + qCDebug(lcNetMon, "Could not get the LUID for the interface."); return false; } GUID guid; if (ConvertInterfaceLuidToGuid(&luid, &guid) != NO_ERROR) { - qCWarning(lcNetMon, "Could not get the GUID for the interface."); + qCDebug(lcNetMon, "Could not get the GUID for the interface."); return false; } ComPtr<INetworkConnection> connection = getNetworkConnectionFromAdapterGuid(guid); if (!connection) { - qCWarning(lcNetMon, "Could not get the INetworkConnection instance for the adapter GUID."); + qCDebug(lcNetMon, "Could not get the INetworkConnection instance for the adapter GUID."); return false; } auto hr = connection->GetConnectionId(&guid); if (FAILED(hr)) { - qCWarning(lcNetMon) << "Failed to get the connection's GUID:" << errorStringFromHResult(hr); + qCDebug(lcNetMon) << "Failed to get the connection's GUID:" + << QSystemError::windowsComString(hr); return false; } currentConnectionId = guid; @@ -302,19 +270,19 @@ bool QNetworkConnectionEvents::setTarget(const QNetworkInterface &iface) bool QNetworkConnectionEvents::startMonitoring() { if (currentConnectionId.isNull()) { - qCWarning(lcNetMon, "Can not start monitoring, set targets first"); + qCDebug(lcNetMon, "Can not start monitoring, set targets first"); return false; } if (!connectionPoint) { - qCWarning(lcNetMon, + qCDebug(lcNetMon, "We don't have the connection point, cannot start listening to events!"); return false; } auto hr = connectionPoint->Advise(this, &cookie); if (FAILED(hr)) { - qCWarning(lcNetMon) << "Failed to subscribe to network connectivity events:" - << errorStringFromHResult(hr); + qCDebug(lcNetMon) << "Failed to subscribe to network connectivity events:" + << QSystemError::windowsComString(hr); return false; } return true; @@ -324,8 +292,8 @@ bool QNetworkConnectionEvents::stopMonitoring() { auto hr = connectionPoint->Unadvise(cookie); if (FAILED(hr)) { - qCWarning(lcNetMon) << "Failed to unsubscribe from network connection events:" - << errorStringFromHResult(hr); + qCDebug(lcNetMon) << "Failed to unsubscribe from network connection events:" + << QSystemError::windowsComString(hr); return false; } cookie = 0; @@ -335,30 +303,25 @@ bool QNetworkConnectionEvents::stopMonitoring() QNetworkConnectionMonitorPrivate::QNetworkConnectionMonitorPrivate() { - auto hr = CoInitialize(nullptr); - if (FAILED(hr)) { - qCWarning(lcNetMon) << "Failed to initialize COM:" << errorStringFromHResult(hr); - comInitFailed = true; + if (!comHelper.isValid()) return; - } connectionEvents = new QNetworkConnectionEvents(this); } QNetworkConnectionMonitorPrivate::~QNetworkConnectionMonitorPrivate() { - if (comInitFailed) + if (!comHelper.isValid()) return; if (monitoring) stopMonitoring(); connectionEvents.Reset(); - CoUninitialize(); } bool QNetworkConnectionMonitorPrivate::setTargets(const QHostAddress &local, const QHostAddress &remote) { - if (comInitFailed) + if (!comHelper.isValid()) return false; QNetworkInterface iface = getInterfaceFromHostAddress(local); @@ -369,7 +332,7 @@ bool QNetworkConnectionMonitorPrivate::setTargets(const QHostAddress &local, addressEntries.cbegin(), addressEntries.cend(), [&local](const QNetworkAddressEntry &entry) { return entry.ip() == local; }); if (Q_UNLIKELY(it == addressEntries.cend())) { - qCWarning(lcNetMon, "The address entry we were working with disappeared"); + qCDebug(lcNetMon, "The address entry we were working with disappeared"); return false; } sameSubnet = remote.isInSubnet(local, it->prefixLength()); @@ -423,11 +386,11 @@ QNetworkConnectionMonitor::~QNetworkConnectionMonitor() = default; bool QNetworkConnectionMonitor::setTargets(const QHostAddress &local, const QHostAddress &remote) { if (isMonitoring()) { - qCWarning(lcNetMon, "Monitor is already active, call stopMonitoring() first"); + qCDebug(lcNetMon, "Monitor is already active, call stopMonitoring() first"); return false; } if (local.isNull()) { - qCWarning(lcNetMon, "Invalid (null) local address, cannot create a reachability target"); + qCDebug(lcNetMon, "Invalid (null) local address, cannot create a reachability target"); return false; } // Silently return false for loopback addresses instead of printing warnings later @@ -441,7 +404,7 @@ bool QNetworkConnectionMonitor::startMonitoring() { Q_D(QNetworkConnectionMonitor); if (isMonitoring()) { - qCWarning(lcNetMon, "Monitor is already active, call stopMonitoring() first"); + qCDebug(lcNetMon, "Monitor is already active, call stopMonitoring() first"); return false; } return d->startMonitoring(); @@ -456,7 +419,7 @@ void QNetworkConnectionMonitor::stopMonitoring() { Q_D(QNetworkConnectionMonitor); if (!isMonitoring()) { - qCWarning(lcNetMon, "stopMonitoring was called when not monitoring!"); + qCDebug(lcNetMon, "stopMonitoring was called when not monitoring!"); return; } d->stopMonitoring(); |