[evolution] [win32] Implement network status detection



commit 8a8e79622eadb6c2577e77f5a3d7655e743dd219
Author: Fridrich Strba <fridrich strba bluewin ch>
Date:   Tue Mar 23 18:54:37 2010 +0100

    [win32] Implement network status detection
    
    The implementation is done using System Event Notification Service
    by implementing ConnectionMade ConnectionMadeNoQOCInfo and
    ConnectionLost methods of ISensNetwork interface.
    
    Introduces C++ dependency for Windows port only

 configure.ac                                    |   22 ++
 modules/Makefile.am                             |    7 +-
 modules/windows-sens/Makefile.am                |   19 ++
 modules/windows-sens/evolution-windows-sens.cxx |  257 +++++++++++++++++++++++
 4 files changed, 304 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index fc9ef87..6a2ee14 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1143,6 +1143,27 @@ fi
 AM_CONDITIONAL([ENABLE_NETWORK_MANAGER], [test "$enable_nm" = yes])
 
 dnl ******************************
+dnl Check for Windows SENS API
+dnl ******************************
+AC_ARG_ENABLE([sens],
+	[AS_HELP_STRING([--enable-sens],
+	[enable Windows SENS support (default=yes)])],
+	[enable_sens=$enableval],[enable_sens=yes])
+AC_MSG_CHECKING([if Windows SENS support is enabled])
+AC_MSG_RESULT([$enable_sens])
+if test "$enable_sens" = yes; then
+	AC_PROG_CXX
+	AC_CHECK_HEADERS([eventsys.h sensevts.h],[ enable_sens="yes" ],[ enable_sens="no" ])
+fi
+if test "$enable_sens" = yes; then
+	SENS_LIBS="-lole32 -loleaut32 -luuid"
+	AC_SUBST(HAVE_SENS)
+	AC_SUBST(SENS_LIBS)
+fi
+
+AM_CONDITIONAL([ENABLE_WINDOWS_SENS], [test "$enable_sens" = yes])
+
+dnl ******************************
 dnl Camel Flags
 dnl ******************************
 EVO_SET_COMPILE_FLAGS(CAMEL, camel-provider-1.2, $MANUAL_NSS_CFLAGS, $MOXILLA_NSS_CFLAGS)
@@ -1693,6 +1714,7 @@ modules/network-manager/Makefile
 modules/plugin-lib/Makefile
 modules/plugin-mono/Makefile
 modules/plugin-python/Makefile
+modules/windows-sens/Makefile
 plugins/Makefile
 plugins/addressbook-file/Makefile
 plugins/attachment-reminder/Makefile
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 0b6ccf2..653d1b6 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -10,6 +10,10 @@ if ENABLE_NETWORK_MANAGER
 NETWORK_MANAGER_DIR = network-manager
 endif
 
+if ENABLE_WINDOWS_SENS
+WINDOWS_SENS_DIR = windows-sens
+endif
+
 SUBDIRS = \
 	addressbook \
 	calendar \
@@ -17,6 +21,7 @@ SUBDIRS = \
 	plugin-lib \
 	$(MONO_DIR) \
 	$(PYTHON_DIR) \
-	$(NETWORK_MANAGER_DIR)
+	$(NETWORK_MANAGER_DIR) \
+	$(WINDOWS_SENS_DIR)
 
 -include $(top_srcdir)/git.mk
diff --git a/modules/windows-sens/Makefile.am b/modules/windows-sens/Makefile.am
new file mode 100644
index 0000000..29b027f
--- /dev/null
+++ b/modules/windows-sens/Makefile.am
@@ -0,0 +1,19 @@
+module_LTLIBRARIES = libevolution-module-windows-sens.la
+
+libevolution_module_windows_sens_la_CPPFLAGS =		\
+	-I$(top_srcdir)						\
+	-DG_LOG_DOMAIN=\"evolution-windows-sens\"		\
+	$(GNOME_PLATFORM_CFLAGS)
+
+libevolution_module_windows_sens_la_SOURCES =		\
+	evolution-windows-sens.cxx
+
+libevolution_module_windows_sens_la_LIBADD =			\
+	$(top_builddir)/shell/libeshell.la			\
+	$(GNOME_PLATFORM_LIBS)					\
+	$(SENS_LIBS)
+
+libevolution_module_windows_sens_la_LDFLAGS =		\
+	-module -avoid-version $(NO_UNDEFINED)
+
+-include $(top_srcdir)/git.mk
diff --git a/modules/windows-sens/evolution-windows-sens.cxx b/modules/windows-sens/evolution-windows-sens.cxx
new file mode 100644
index 0000000..b6328e9
--- /dev/null
+++ b/modules/windows-sens/evolution-windows-sens.cxx
@@ -0,0 +1,257 @@
+/*
+ * evolution-windows-sens.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define INITGUID
+#include <windows.h>
+#include <eventsys.h>
+#include <sensevts.h>
+#include <stdio.h>
+
+
+#include <shell/e-shell.h>
+#include <e-util/e-extension.h>
+
+/* Standard GObject macros */
+#define E_TYPE_WINDOWS_SENS \
+	(e_windows_sens_get_type ())
+#define E_WINDOWS_SENS(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_WINDOWS_SENS, EWindowsSENS))
+
+typedef struct _EWindowsSENS EWindowsSENS;
+typedef struct _EWindowsSENSClass EWindowsSENSClass;
+
+struct _EWindowsSENS {
+	EExtension parent;
+};
+
+struct _EWindowsSENSClass {
+	EExtensionClass parent_class;
+};
+
+/* Module Entry Points */
+void e_module_load (GTypeModule *type_module);
+void e_module_unload (GTypeModule *type_module);
+
+/* Forward Declarations */
+GType e_windows_sens_get_type (void);
+
+G_DEFINE_DYNAMIC_TYPE (EWindowsSENS, e_windows_sens, E_TYPE_EXTENSION)
+
+static EShell *
+windows_sens_get_shell (EWindowsSENS *extension)
+{
+	EExtensible *extensible;
+
+	extensible = e_extension_get_extensible (E_EXTENSION (extension));
+
+	return E_SHELL (extensible);
+}
+
+class MySensNetwork : public IDispatch
+{
+private:
+    long ref;
+    EWindowsSENS *mpEWS;
+
+public:
+    MySensNetwork (EWindowsSENS *ews) :
+		ref(1),
+		mpEWS(ews)
+    {}
+
+    HRESULT WINAPI QueryInterface (REFIID iid, void ** ppv)
+    {
+        if (IsEqualIID (iid, IID_IUnknown) || IsEqualIID (iid, IID_IDispatch) || IsEqualIID (iid, IID_ISensNetwork)) {
+            *ppv = this;
+            AddRef();
+            return S_OK;
+        }
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    ULONG WINAPI AddRef ()
+    {
+        return InterlockedIncrement (&ref);
+    }
+
+    ULONG WINAPI Release ()
+    {
+        int tmp = InterlockedDecrement (&ref);
+        return tmp;
+    }
+
+    HRESULT WINAPI GetTypeInfoCount (unsigned FAR*)
+    {
+        return E_NOTIMPL;
+    }
+
+    HRESULT WINAPI GetTypeInfo (unsigned, LCID, ITypeInfo FAR* FAR*)
+    {
+        return E_NOTIMPL;
+    }
+
+    HRESULT WINAPI GetIDsOfNames (REFIID, OLECHAR FAR* FAR*, unsigned, LCID, DISPID FAR*)
+    {
+        return E_NOTIMPL;
+    }
+
+    HRESULT WINAPI Invoke (DISPID, REFIID, LCID, WORD, DISPPARAMS FAR*, VARIANT FAR*, EXCEPINFO FAR*, unsigned FAR*)
+    {
+        return E_NOTIMPL;
+    }
+
+// ISensNetwork methods:
+    virtual HRESULT WINAPI ConnectionMade (BSTR, ULONG ulType, LPSENS_QOCINFO*)
+    {
+		if (ulType) {
+			EShell *shell = windows_sens_get_shell (mpEWS);
+			e_shell_set_network_available (shell, TRUE);
+		}
+		return S_OK;
+	}
+
+    virtual HRESULT WINAPI ConnectionMadeNoQOCInfo (BSTR, ULONG)
+    {
+		//Always followed by ConnectionMade
+		return S_OK;
+	}
+
+    virtual HRESULT WINAPI ConnectionLost (BSTR, ULONG ulType)
+    {
+		if (ulType) {
+			EShell *shell = windows_sens_get_shell (mpEWS);
+			e_shell_set_network_available (shell, FALSE);
+		}
+		return S_OK;
+	}
+};
+
+/* 4E14FB9F-2E22-11D1-9964-00C04FBBB345 */
+DEFINE_GUID(IID_IEventSystem, 0x4E14FB9F, 0x2E22, 0x11D1, 0x99, 0x64, 0x00, 0xC0, 0x4F, 0xBB, 0xB3, 0x45);
+
+/* 4A6B0E15-2E38-11D1-9965-00C04FBBB345 */
+DEFINE_GUID(IID_IEventSubscription, 0x4A6B0E15, 0x2E38, 0x11D1, 0x99, 0x65, 0x00, 0xC0, 0x4F, 0xBB, 0xB3, 0x45);
+
+/* d597bab1-5b9f-11d1-8dd2-00aa004abd5e */
+DEFINE_GUID(IID_ISensNetwork, 0xd597bab1, 0x5b9f, 0x11d1, 0x8d, 0xd2, 0x00, 0xaa, 0x00, 0x4a, 0xbd, 0x5e);
+
+/* 4E14FBA2-2E22-11D1-9964-00C04FBBB345 */
+DEFINE_GUID(CLSID_CEventSystem, 0x4E14FBA2, 0x2E22, 0x11D1, 0x99, 0x64, 0x00, 0xC0, 0x4F, 0xBB, 0xB3, 0x45);
+
+/* 7542e960-79c7-11d1-88f9-0080c7d771bf */
+DEFINE_GUID(CLSID_CEventSubscription, 0x7542e960, 0x79c7, 0x11d1, 0x88, 0xf9, 0x00, 0x80, 0xc7, 0xd7, 0x71, 0xbf);
+
+static void
+windows_sens_constructed (GObject *object)
+{
+	static IEventSystem *pIEventSystem =0;
+	static IEventSubscription* pIEventSubscription = 0;
+	WCHAR buffer[64];
+	static const char* eventclassid="{D5978620-5B9F-11D1-8DD2-00AA004ABD5E}";
+    static const char* methods[]={"ConnectionMade","ConnectionMadeNoQOCInfo","ConnectionLost"};
+    static const char* names[]={"EWS_ConnectionMade","EWS_ConnectionMadeNoQOCInfo","EWS_ConnectionLost"};
+    static const char* subids[]={"{cd1dcbd6-a14d-4823-a0d2-8473afde360f}","{a82f0e80-1305-400c-ba56-375ae04264a1}",
+                           "{45233130-b6c3-44fb-a6af-487c47cee611}"};
+
+	EWindowsSENS *extension = (E_WINDOWS_SENS (object));
+	static MySensNetwork *pISensNetwork = new MySensNetwork (extension);
+
+	CoInitialize(0);
+
+	HRESULT res=CoCreateInstance (CLSID_CEventSystem, 0,CLSCTX_SERVER,IID_IEventSystem,(void**)&pIEventSystem);
+
+	for (int i=0; i<3; i++)
+	{
+		res=CoCreateInstance (CLSID_CEventSubscription, 0, CLSCTX_SERVER, IID_IEventSubscription, (LPVOID*)&pIEventSubscription);
+		MultiByteToWideChar (0, 0, eventclassid, -1, buffer, 64);
+		res=pIEventSubscription->put_EventClassID (buffer);
+		res=pIEventSubscription->put_SubscriberInterface ((IUnknown*)pISensNetwork);
+		MultiByteToWideChar (0, 0, methods[i], -1, buffer, 64);
+		res=pIEventSubscription->put_MethodName (buffer);
+		MultiByteToWideChar (0, 0, names[i], -1, buffer, 64);
+		res=pIEventSubscription->put_SubscriptionName (buffer);
+		MultiByteToWideChar (0, 0, subids[i], -1, buffer, 64);
+		res=pIEventSubscription->put_SubscriptionID (buffer);
+		res=pIEventSystem->Store (PROGID_EventSubscription, (IUnknown*)pIEventSubscription);
+		pIEventSubscription->Release ();
+		pIEventSubscription=0;
+	}
+
+	typedef BOOL (WINAPI* IsNetworkAlive_t) (LPDWORD);
+
+	IsNetworkAlive_t pIsNetworkAlive = NULL;
+
+	HMODULE hDLL=LoadLibrary ("sensapi.dll");
+
+	BOOL alive = TRUE;
+	if ((pIsNetworkAlive=(IsNetworkAlive_t) GetProcAddress (hDLL, "IsNetworkAlive"))) {
+		DWORD Network;
+		alive=pIsNetworkAlive (&Network);
+	}
+
+	FreeLibrary(hDLL);
+
+	EShell *shell = windows_sens_get_shell (extension);
+
+	e_shell_set_network_available (shell, alive);
+}
+
+static void
+e_windows_sens_class_init (EWindowsSENSClass *_class)
+{
+	GObjectClass *object_class;
+	EExtensionClass *extension_class;
+
+	object_class = G_OBJECT_CLASS (_class);
+	object_class->constructed = windows_sens_constructed;
+
+	extension_class = E_EXTENSION_CLASS (_class);
+	extension_class->extensible_type = E_TYPE_SHELL;
+}
+
+static void
+e_windows_sens_class_finalize (EWindowsSENSClass *_class)
+{
+	CoUninitialize();
+}
+
+static void
+e_windows_sens_init (EWindowsSENS *extension)
+{
+}
+
+G_MODULE_EXPORT void
+e_module_load (GTypeModule *type_module)
+{
+	e_windows_sens_register_type (type_module);
+}
+
+G_MODULE_EXPORT void
+e_module_unload (GTypeModule *type_module)
+{
+}
+
+#ifdef __cplusplus
+}
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]