Skip to content
Snippets Groups Projects
Select Git revision
  • 4628559534d7846fdced06fccff1ccc6d11c9ce7
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/201911
  • release/releaseWindowsTestOne
  • release/windowsReleaseTest
  • release/releaseTest
  • release/releaseWindowsTest
  • release/201910
  • release/qt/201910
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • 4.0.0
  • 2.2.0
  • 2.1.0
  • 2.0.1
  • 2.0.0
  • 1.4.1
  • 1.4.0
  • 1.3.0
  • 1.2.0
  • 1.1.0
31 results

tls_session.h

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    connectivitymonitor.cpp 4.30 KiB
    /*
     * Copyright (C) 2019-2020 by Savoir-faire Linux
     * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or
     * (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    #include "connectivitymonitor.h"
    
    #include <QDebug>
    
    #ifdef Q_OS_WIN
    #include <atlbase.h>
    #include <netlistmgr.h>
    
    class NetworkEventHandler : public INetworkListManagerEvents
    {
    public:
        NetworkEventHandler()
            : m_lRefCnt(1){};
        virtual ~NetworkEventHandler(){};
    
        HRESULT STDMETHODCALLTYPE
        QueryInterface(REFIID riid, void **ppvObject)
        {
            HRESULT hr = S_OK;
            if (IsEqualIID(riid, IID_IUnknown)) {
                *ppvObject = (IUnknown *) this;
            } else if (IsEqualIID(riid, IID_INetworkListManagerEvents)) {
                *ppvObject = (INetworkListManagerEvents *) this;
            } else {
                hr = E_NOINTERFACE;
            }
    
            return hr;
        };
        ULONG STDMETHODCALLTYPE
        AddRef()
        {
            return (ULONG) InterlockedIncrement(&m_lRefCnt);
        };
        ULONG STDMETHODCALLTYPE
        Release()
        {
            LONG res = InterlockedDecrement(&m_lRefCnt);
            if (res == 0) {
                delete this;
            }
            return (ULONG) res;
        };
    
        virtual HRESULT STDMETHODCALLTYPE
        ConnectivityChanged(NLM_CONNECTIVITY newConnectivity)
        {
            qDebug() << "connectivity changed: " << newConnectivity;
            if (connectivityChangedCb_) {
                connectivityChangedCb_();
            }
            return S_OK;
        };
    
        void
        setOnConnectivityChangedCallBack(std::function<void()> &&cb)
        {
            connectivityChangedCb_ = cb;
        };
    
    private:
        LONG m_lRefCnt;
    
        std::function<void()> connectivityChangedCb_;
    };
    
    ConnectivityMonitor::ConnectivityMonitor(QObject *parent)
        : QObject(parent)
    {
        CoInitialize(NULL);
    
        IUnknown *pUnknown = NULL;
    
        HRESULT hr = CoCreateInstance(CLSID_NetworkListManager,
                                      NULL,
                                      CLSCTX_ALL,
                                      IID_IUnknown,
                                      (void **) &pUnknown);
        if (FAILED(hr)) {
            return;
        }
    
        pNetworkListManager_ = NULL;
        hr = pUnknown->QueryInterface(IID_INetworkListManager, (void **) &pNetworkListManager_);
        if (FAILED(hr)) {
            destroy();
            pUnknown->Release();
            return;
        }
    
        pCPContainer_ = NULL;
        hr = pNetworkListManager_->QueryInterface(IID_IConnectionPointContainer,
                                                  (void **) &pCPContainer_);
        if (FAILED(hr)) {
            destroy();
            pUnknown->Release();
            return;
        }
    
        pConnectPoint_ = NULL;
        hr = pCPContainer_->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint_);
        if (SUCCEEDED(hr)) {
            cookie_ = NULL;
            netEventHandler_ = new NetworkEventHandler;
            netEventHandler_->setOnConnectivityChangedCallBack([this] { emit connectivityChanged(); });
            hr = pConnectPoint_->Advise((IUnknown *) netEventHandler_, &cookie_);
        } else {
            destroy();
        }
    
        pUnknown->Release();
    }
    
    bool
    ConnectivityMonitor::isOnline()
    {
        if (!pNetworkListManager_) {
            return false;
        }
        VARIANT_BOOL IsConnect = VARIANT_FALSE;
        HRESULT hr = pNetworkListManager_->get_IsConnectedToInternet(&IsConnect);
        if (SUCCEEDED(hr)) {
            return IsConnect == VARIANT_TRUE;
        }
        return false;
    }
    
    void
    ConnectivityMonitor::destroy()
    {
        if (pConnectPoint_) {
            pConnectPoint_->Unadvise(cookie_);
            pConnectPoint_->Release();
        }
        if (pCPContainer_) {
            pCPContainer_->Release();
        }
        if (pNetworkListManager_) {
            pNetworkListManager_->Release();
            pNetworkListManager_ = NULL;
        }
    }
    
    ConnectivityMonitor::~ConnectivityMonitor()
    {
        destroy();
        CoUninitialize();
    }
    #endif // Q_OS_WIN