summaryrefslogtreecommitdiffstats
path: root/src/plugins/networkinformationbackends
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2021-05-25 15:42:10 +0200
committerMårten Nordheim <marten.nordheim@qt.io>2021-06-08 14:54:15 +0200
commit2a60c4b99f0929341aa3b5a15373f6e675ff7ad4 (patch)
treed87e34fab30cd0de7a7f0d754824467d57860b11 /src/plugins/networkinformationbackends
parentc8cb2409477bdc3bc41d6bbdfc5055441cda084f (diff)
QNetworkInformation: Captive portal support for Windows
Task-number: QTBUG-93848 Change-Id: Ic1ca895a73c98772aba900bbc3be18ba62be6c0f Reviewed-by: Alex Blasche <alexander.blasche@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/plugins/networkinformationbackends')
-rw-r--r--src/plugins/networkinformationbackends/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp56
1 files changed, 55 insertions, 1 deletions
diff --git a/src/plugins/networkinformationbackends/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp b/src/plugins/networkinformationbackends/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp
index c6b0a6e79b..ffed43aac7 100644
--- a/src/plugins/networkinformationbackends/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp
+++ b/src/plugins/networkinformationbackends/networklistmanager/qnetworklistmanagernetworkinformationbackend.cpp
@@ -41,6 +41,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/private/qobject_p.h>
+#include <QtCore/qscopeguard.h>
#include <objbase.h>
#include <netlistmgr.h>
@@ -120,7 +121,8 @@ public:
static QNetworkInformation::Features featuresSupportedStatic()
{
- return QNetworkInformation::Features(QNetworkInformation::Feature::Reachability);
+ return QNetworkInformation::Features(QNetworkInformation::Feature::Reachability
+ | QNetworkInformation::Feature::CaptivePortal);
}
[[nodiscard]] bool start();
@@ -131,6 +133,7 @@ private:
bool event(QEvent *event) override;
void setConnectivity(NLM_CONNECTIVITY newConnectivity);
+ void checkCaptivePortal();
ComPtr<QNetworkListManagerEvents> managerEvents;
@@ -193,6 +196,8 @@ public:
[[nodiscard]] bool start();
bool stop();
+ [[nodiscard]] bool checkBehindCaptivePortal();
+
signals:
void connectivityChanged(NLM_CONNECTIVITY);
@@ -288,6 +293,44 @@ bool QNetworkListManagerEvents::stop()
return true;
}
+bool QNetworkListManagerEvents::checkBehindCaptivePortal()
+{
+ if (!networkListManager)
+ return false;
+ ComPtr<IEnumNetworks> networks;
+ HRESULT hr =
+ networkListManager->GetNetworks(NLM_ENUM_NETWORK_CONNECTED, networks.GetAddressOf());
+ if (FAILED(hr) || networks == nullptr)
+ return false;
+
+ // @note: This checks all connected networks, but that might not be necessary
+ ComPtr<INetwork> network;
+ hr = networks->Next(1, network.GetAddressOf(), nullptr);
+ while (SUCCEEDED(hr) && network != nullptr) {
+ ComPtr<IPropertyBag> propertyBag;
+ hr = network.As(&propertyBag);
+ if (SUCCEEDED(hr) && propertyBag != nullptr) {
+ VARIANT variant;
+ VariantInit(&variant);
+ const auto scopedVariantClear = qScopeGuard([&variant]() { VariantClear(&variant); });
+
+ const wchar_t *versions[] = { NA_InternetConnectivityV6, NA_InternetConnectivityV4 };
+ for (const auto version : versions) {
+ hr = propertyBag->Read(version, &variant, nullptr);
+ if (SUCCEEDED(hr)
+ && (V_UINT(&variant) & NLM_INTERNET_CONNECTIVITY_WEBHIJACK)
+ == NLM_INTERNET_CONNECTIVITY_WEBHIJACK) {
+ return true;
+ }
+ }
+ }
+
+ hr = networks->Next(1, network.GetAddressOf(), nullptr);
+ }
+
+ return false;
+}
+
QNetworkListManagerNetworkInformationBackend::QNetworkListManagerNetworkInformationBackend()
{
auto hr = CoInitialize(nullptr);
@@ -314,9 +357,20 @@ void QNetworkListManagerNetworkInformationBackend::setConnectivity(NLM_CONNECTIV
!= reachabilityFromNLM_CONNECTIVITY(newConnectivity)) {
connectivity = newConnectivity;
setReachability(reachabilityFromNLM_CONNECTIVITY(newConnectivity));
+
+ // @future: only check if signal is connected
+ checkCaptivePortal();
}
}
+void QNetworkListManagerNetworkInformationBackend::checkCaptivePortal()
+{
+ const bool behindPortal = managerEvents->checkBehindCaptivePortal();
+ using TriState = QNetworkInformation::TriState;
+ const auto triState = behindPortal ? TriState::True : TriState::False;
+ setBehindCaptivePortal(triState);
+}
+
bool QNetworkListManagerNetworkInformationBackend::event(QEvent *event)
{
if (event->type() == QEvent::ThreadChange && monitoring) {