8000 监控系统事件(网卡) · Issue #55 · holdyounger/ScopeBlog · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
监控系统事件(网卡) #55
Open
@holdyounger

Description

@holdyounger

监控系统事件(网卡)

#pragma once

#include <netlistmgr.h>
#include <atomic>

std::atomic_bool g_bNetWorkOnline(true);

class CNetworkListManagerEvent : public INetworkListManagerEvents
{
public:
	CNetworkListManagerEvent(std::function<void(bool)> netChangedHandler) 
		: m_ref(1)
		, netChangedHandler_(netChangedHandler)
	{

	}

	~CNetworkListManagerEvent()
	{

	}

	HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject)
	{
		HRESULT Result = S_OK;
		if (IsEqualIID(riid, IID_IUnknown))
		{
			*ppvObject = (IUnknown*)this;
		}
		else if (IsEqualIID(riid, IID_INetworkListManagerEvents))
		{
			*ppvObject = (INetworkListManagerEvents*)this;
		}
		else
		{
			Result = E_NOINTERFACE;
		}

		return Result;
	}

	ULONG STDMETHODCALLTYPE AddRef()
	{
		return (ULONG)InterlockedIncrement(&m_ref);
	}

	ULONG STDMETHODCALLTYPE Release()
	{
		LONG Result = InterlockedDecrement(&m_ref);
		if (Result == 0)
			delete this;
		return (ULONG)Result;
	}

	virtual HRESULT STDMETHODCALLTYPE ConnectivityChanged(
		/* [in] */ NLM_CONNECTIVITY newConnectivity)
	{
		if (newConnectivity == NLM_CONNECTIVITY_DISCONNECTED)
		{
			SP_DEV_LOGT("internet status changed. connect closed");

			// 网络断开
			netChangedHandler_(false);
		}
		else if ((newConnectivity & NLM_CONNECTIVITY_IPV4_INTERNET) || (newConnectivity & NLM_CONNECTIVITY_IPV6_INTERNET))
		{
			SP_DEV_LOGT("internet status changed. connect success");

			// 网络连接成功
			netChangedHandler_(true);
		}
		return S_OK;
	}

private:
	LONG m_ref;
	std::function<void(bool)> netChangedHandler_;
};


class CNetworkMonitor
{
public:
	CNetworkMonitor() {};
	~CNetworkMonitor() {};

private:
	// 监控网络状态变化
	static void InitNetworkMonitor()
	{
		SP_DEV_LOGT("InitNetworkMonitor");

		bool bSuccess = false;
		CoInitialize(NULL);
		//
		//  通过NLA接口获取网络状态
		//
		IUnknown* pUnknown = NULL;
		HRESULT Result = CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL, IID_IUnknown, (void**)&pUnknown);
		if (SUCCEEDED(Result))
		{
			INetworkListManager* pNetworkListManager = NULL;
			Result = pUnknown->QueryInterface(IID_INetworkListManager, (void**)&pNetworkListManager);
			if (SUCCEEDED(Result))
			{
				VARIANT_BOOL IsConnect = VARIANT_FALSE;
				Result = pNetworkListManager->get_IsConnectedToInternet(&IsConnect);
				if (SUCCEEDED(Result))
				{
					SP_DEV_LOGT("connect to internet:%s", IsConnect == VARIANT_TRUE ? "TRUE" : "FALSE");
				}

				IConnectionPointContainer* pCPContainer = NULL;
				Result = pNetworkListManager->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPContainer);
				if (SUCCEEDED(Result))
				{
					IConnectionPoint* pConnectPoint = NULL;
					Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint);
					if (SUCCEEDED(Result))
					{
						DWORD Cookie = NULL;

						CNetworkMonitor networkMonitor;
						std::function<void(bool)> monitorFunc = std::bind(&CNetworkMonitor::NetworkStatusChangedCallback, networkMonitor, std::placeholders::_1);
						CNetworkListManagerEvent* pNetEvent = new(std::nothrow) CNetworkListManagerEvent(monitorFunc);
						if (pNetEvent)
						{
							Result = pConnectPoint->Advise((IUnknown*)pNetEvent, &Cookie);
							if (SUCCEEDED(Result))
							{
								SP_DEV_LOGT("InitNetworkMonitor success");
								bSuccess = true;

								MSG msg;
								while (GetMessage(&msg, NULL, 0, 0))
								{
									TranslateMessage(&msg);
									DispatchMessage(&msg);

									if (msg.message == WM_QUIT)
									{
										break;
									}
								}

								pConnectPoint->Unadvise(Cookie);
								pConnectPoint->Release();
							}
						}
					}
					pCPContainer->Release();
				}
				pNetworkListManager->Release();
			}
			pUnknown->Release();
		}
		CoUninitialize();
	}

	void NetworkStatusChangedCallback(bool status)
	{
		g_bNetWorkOnline = status;
		if (status)
		{
			if (g_sp_trust_model.get())
			{
				if (g_sp_trust_model->IsOnline())
				{
					//休眠唤醒后网络连接成功,自动发送一次心跳
					SP_LOGI("Sleep wakes up and automatically triggers a heartbeat");
					g_sp_trust_model->OnWakeToSendHeartBeat();

					SP_LOGI("rebuild trust nc");

					if (g_sp_trust_model->Session()->NeedsL3Tunnel() && !g_sp_trust_model->Session()->IsTunnelSvrsEmpty())
					{
						// 网络连接成功后自动触发重连
						std::thread buildUtunThread([] {
							g_sp_trust_model->NotifyUpMessage(SP_TRUST_TOPIC_BUILD_UTUN, SPJSONObject());
							});
						buildUtunThread.detach();
					}
				}
				else
				{
					SP_LOGI("No login, will not rebuild trust nc");
				}
			}
			else
			{
				SP_LOGI("rebuild trust nc - g_sp_trust_model is null");
			}
		}
	}

public:
	void StartMonitor()
	{
		std::thread monitorThread(&InitNetworkMonitor);
		monitorThread.detach();
	}
};

blog link 监控系统事件(网卡)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0