From 90914bb2deaa6b2b1014f4bab31aa4016972b258 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Sun, 12 Apr 2020 05:25:22 +0300 Subject: [PATCH] [windows] init internet connectivity events checker functional (vista+ supported only) Signed-off-by: R4SAS --- Makefile | 2 +- Makefile.mingw | 2 ++ Win32/Win32App.cpp | 17 +++++---- Win32/Win32NetState.cpp | 59 +++++++++++++++++++++++++++++++ Win32/Win32NetState.h | 77 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 Win32/Win32NetState.cpp create mode 100644 Win32/Win32NetState.h diff --git a/Makefile b/Makefile index a814aecf..35d76b82 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ else ifneq (, $(findstring freebsd, $(SYS))$(findstring openbsd, $(SYS))) DAEMON_SRC += $(DAEMON_SRC_DIR)/UnixDaemon.cpp include Makefile.bsd else ifneq (, $(findstring mingw, $(SYS))$(findstring cygwin, $(SYS))) - DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp + DAEMON_SRC += Win32/DaemonWin32.cpp Win32/Win32Service.cpp Win32/Win32App.cpp Win32/Win32NetState.cpp include Makefile.mingw else # not supported $(error Not supported platform) diff --git a/Makefile.mingw b/Makefile.mingw index 17be71eb..1b1b4b25 100644 --- a/Makefile.mingw +++ b/Makefile.mingw @@ -27,6 +27,8 @@ LDLIBS += \ -lws2_32 \ -lgdi32 \ -liphlpapi \ + -lole32 \ + -luuid \ -lstdc++ \ -lpthread diff --git a/Win32/Win32App.cpp b/Win32/Win32App.cpp index df87da3a..dd614df2 100644 --- a/Win32/Win32App.cpp +++ b/Win32/Win32App.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -11,7 +12,7 @@ #include "resource.h" #include "Daemon.h" #include "Win32App.h" -#include +#include "Win32NetState.h" #define ID_ABOUT 2000 #define ID_EXIT 2001 @@ -35,7 +36,7 @@ namespace i2p namespace win32 { static DWORD GracefulShutdownEndtime = 0; - + typedef DWORD (* IPN)(); IPN GetTickCountLocal = (IPN)GetProcAddress (GetModuleHandle ("KERNEL32.dll"), "GetTickCount"); @@ -338,11 +339,6 @@ namespace win32 PostMessage (hWnd, WM_CLOSE, 0, 0); // exit return 0; } - case FRAME_UPDATE_TIMER: - { - InvalidateRect(hWnd, NULL, TRUE); - return 0; - } case IDT_GRACEFUL_TUNNELCHECK_TIMER: { if (i2p::tunnel::tunnels.CountTransitTunnels() == 0) @@ -351,6 +347,11 @@ namespace win32 SetTimer (hWnd, IDT_GRACEFUL_TUNNELCHECK_TIMER, 1000, nullptr); return 0; } + case FRAME_UPDATE_TIMER: + { + InvalidateRect(hWnd, NULL, TRUE); + return 0; + } } break; } @@ -411,6 +412,7 @@ namespace win32 MessageBox(NULL, "Failed to create main window", TEXT("Warning!"), MB_ICONERROR | MB_OK | MB_TOPMOST); return false; } + SubscribeToEvents(); return true; } @@ -430,6 +432,7 @@ namespace win32 HWND hWnd = FindWindow (I2PD_WIN32_CLASSNAME, TEXT("i2pd")); if (hWnd) PostMessage (hWnd, WM_COMMAND, MAKEWPARAM(ID_EXIT, 0), 0); + UnSubscribeFromEvents(); UnregisterClass (I2PD_WIN32_CLASSNAME, GetModuleHandle(NULL)); } diff --git a/Win32/Win32NetState.cpp b/Win32/Win32NetState.cpp new file mode 100644 index 00000000..f6843ebc --- /dev/null +++ b/Win32/Win32NetState.cpp @@ -0,0 +1,59 @@ +#if WINVER != 0x0501 // supported since Vista +#include "Win32NetState.h" +#include +#include "Log.h" + +IUnknown *pUnknown = NULL; +INetworkListManager *pNetworkListManager = NULL; +IConnectionPointContainer *pCPContainer = NULL; +DWORD Cookie = 0; +IConnectionPoint *pConnectPoint = NULL; + +void SubscribeToEvents() +{ + LogPrint(eLogInfo, "NetState: Trying to subscribe to NetworkListManagerEvents"); + CoInitialize(NULL); + + HRESULT Result = CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL, IID_IUnknown, (void **)&pUnknown); + if (SUCCEEDED(Result)) + { + Result = pUnknown->QueryInterface(IID_INetworkListManager, (void **)&pNetworkListManager); + if (SUCCEEDED(Result)) + { + /* VARIANT_BOOL IsConnect = VARIANT_FALSE; + Result = pNetworkListManager->IsConnectedToInternet(&IsConnect); + if (SUCCEEDED(Result)) + LogPrint(eLogInfo, "NetState: IsConnect Result:", IsConnect == VARIANT_TRUE ? "TRUE" : "FALSE"); */ + + Result = pNetworkListManager->QueryInterface(IID_IConnectionPointContainer, (void **)&pCPContainer); + if (SUCCEEDED(Result)) + { + Result = pCPContainer->FindConnectionPoint(IID_INetworkListManagerEvents, &pConnectPoint); + if(SUCCEEDED(Result)) + { + CNetworkListManagerEvent *NetEvent = new CNetworkListManagerEvent; + Result = pConnectPoint->Advise((IUnknown *)NetEvent, &Cookie); + if (SUCCEEDED(Result)) + LogPrint(eLogInfo, "NetState: Successfully subscribed to NetworkListManagerEvent messages"); + } else + LogPrint(eLogError, "NetState: Unable to find interface connection point"); + } else + LogPrint(eLogError, "NetState: Unable to query NetworkListManager interface"); + } else + LogPrint(eLogError, "NetState: Unable to query global interface"); + } else + LogPrint(eLogError, "NetState: Unable to create INetworkListManager interface"); +} + +void UnSubscribeFromEvents() +{ + // TODO - DETECT EVERY STAGE STATE and call functions depending it !!! + pConnectPoint->Unadvise(Cookie); + pConnectPoint->Release(); + pCPContainer->Release(); + pNetworkListManager->Release(); + pUnknown->Release(); + CoUninitialize(); +} + +#endif // WINVER diff --git a/Win32/Win32NetState.h b/Win32/Win32NetState.h new file mode 100644 index 00000000..3e82aa5e --- /dev/null +++ b/Win32/Win32NetState.h @@ -0,0 +1,77 @@ +#ifndef WIN_32_NETSTATE_H__ +#define WIN_32_NETSTATE_H__ + +#if WINVER != 0x0501 // supported since Vista +#include +#include +#include "Log.h" +#include "Transports.h" + +class CNetworkListManagerEvent : public INetworkListManagerEvents +{ +public: + CNetworkListManagerEvent() : m_ref(1) { } + ~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(NLM_CONNECTIVITY newConnectivity) + { + if (newConnectivity == NLM_CONNECTIVITY_DISCONNECTED) + LogPrint(eLogInfo, "NetState: disconnected from network"); + + if (((int)newConnectivity & (int)NLM_CONNECTIVITY_IPV4_INTERNET) != 0) + LogPrint(eLogInfo, "NetState: connected to internet with IPv4 capability"); + + if (((int)newConnectivity & (int)NLM_CONNECTIVITY_IPV6_INTERNET) != 0) + LogPrint(eLogInfo, "NetState: connected to internet with IPv6 capability"); + + if ( + (((int)newConnectivity & (int)NLM_CONNECTIVITY_IPV4_INTERNET) == 0) && + (((int)newConnectivity & (int)NLM_CONNECTIVITY_IPV6_INTERNET) == 0) + ) + LogPrint(eLogInfo, "NetState: connected without internet access"); + + return S_OK; + } + +private: + + LONG m_ref; +}; + +void SubscribeToEvents(); +void UnSubscribeFromEvents(); + +#else // WINVER == 0x0501 + +void SubscribeToEvents() { } +void UnSubscribeFromEvents() { } + +#endif // WINVER +#endif \ No newline at end of file