diff options
-rw-r--r-- | configure.ac | 38 | ||||
-rw-r--r-- | modules/Makefile.am | 7 | ||||
-rw-r--r-- | modules/windows-sens/Makefile.am | 20 | ||||
-rw-r--r-- | modules/windows-sens/evolution-windows-sens.c | 602 |
4 files changed, 666 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 3f3a2bbef7..882dd1d3a8 100644 --- a/configure.ac +++ b/configure.ac @@ -1143,6 +1143,42 @@ 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]) +if test "x$os_win32" = xyes; then + if test "x$enable_sens" = xyes; then + AC_CHECK_HEADER([rpc.h],[ enable_sens="yes" ],[ enable_sens="no" ]) + fi +else + enable_sens="no" +fi +AC_MSG_CHECKING([if Windows SENS support is enabled]) +AC_MSG_RESULT([$enable_sens]) +if test "$enable_sens" = yes; then + SENS_LIBS="-lole32 -loleaut32 -luuid -lrpcrt4" + AC_CHECK_HEADER([eventsys.h], + [AC_DEFINE([HAVE_EVENTSYS_H], 1, [Have <eventsys.h>])],, + [[ #if HAVE_EVENTSYS_H + #include <eventsys.h> + #endif + ]]) + AC_CHECK_HEADER([sensevts.h], + [AC_DEFINE([HAVE_SENSEVTS_H], 1, [Have <sensevts.h>])],, + [[ #if HAVE_SENSEVTS_H + #include <sensevts.h> + #endif + ]]) + 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 +1729,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 @@ -1760,6 +1797,7 @@ fi echo " LDAP support: $msg_ldap NetworkManager: $enable_nm + Windows SENS: $enable_sens Pilot conduits: $msg_pilot Libnotify: $HAVE_LIBNOTIFY Kerberos 5: $msg_krb5 diff --git a/modules/Makefile.am b/modules/Makefile.am index 0b6ccf22ec..653d1b69c6 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 0000000000..5036642d09 --- /dev/null +++ b/modules/windows-sens/Makefile.am @@ -0,0 +1,20 @@ +module_LTLIBRARIES = libevolution-module-windows-sens.la + +libevolution_module_windows_sens_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -DG_LOG_DOMAIN=\"evolution-windows-sens\" \ + $(GNOME_PLATFORM_CFLAGS) + +libevolution_module_windows_sens_la_SOURCES = \ + evolution-windows-sens.c + +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.c b/modules/windows-sens/evolution-windows-sens.c new file mode 100644 index 0000000000..d228fc02ac --- /dev/null +++ b/modules/windows-sens/evolution-windows-sens.c @@ -0,0 +1,602 @@ +/* + * 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 +#error This file cannot be built with C++ compiler +#endif + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#define INITGUID +#include <windows.h> +#include <rpc.h> + +#ifdef HAVE_EVENTSYS_H +#include <eventsys.h> +#else + +/* Extract relevant typedefs from mingw-w64 headers */ + +typedef struct IEnumEventObject IEnumEventObject; + +const IID IID_IEnumEventObject; +typedef struct IEnumEventObjectVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(IEnumEventObject *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(IEnumEventObject *This); + ULONG (WINAPI *Release)(IEnumEventObject *This); + HRESULT (WINAPI *Clone)(IEnumEventObject *This,IEnumEventObject **ppInterface); + HRESULT (WINAPI *Next)(IEnumEventObject *This,ULONG cReqElem,IUnknown **ppInterface,ULONG *cRetElem); + HRESULT (WINAPI *Reset)(IEnumEventObject *This); + HRESULT (WINAPI *Skip)(IEnumEventObject *This,ULONG cSkipElem); + END_INTERFACE +} IEnumEventObjectVtbl; +struct IEnumEventObject { + CONST_VTBL struct IEnumEventObjectVtbl *lpVtbl; +}; + +typedef struct IEventObjectCollection IEventObjectCollection; + +const IID IID_IEventObjectCollection; +typedef struct IEventObjectCollectionVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(IEventObjectCollection *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(IEventObjectCollection *This); + ULONG (WINAPI *Release)(IEventObjectCollection *This); + HRESULT (WINAPI *GetTypeInfoCount)(IEventObjectCollection *This,UINT *pctinfo); + HRESULT (WINAPI *GetTypeInfo)(IEventObjectCollection *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo); + HRESULT (WINAPI *GetIDsOfNames)(IEventObjectCollection *This,REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId); + HRESULT (WINAPI *Invoke)(IEventObjectCollection *This,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr); + HRESULT (WINAPI *get__NewEnum)(IEventObjectCollection *This,IUnknown **ppUnkEnum); + HRESULT (WINAPI *get_Item)(IEventObjectCollection *This,BSTR objectID,VARIANT *pItem); + HRESULT (WINAPI *get_NewEnum)(IEventObjectCollection *This,IEnumEventObject **ppEnum); + HRESULT (WINAPI *get_Count)(IEventObjectCollection *This,long *pCount); + HRESULT (WINAPI *Add)(IEventObjectCollection *This,VARIANT *item,BSTR objectID); + HRESULT (WINAPI *Remove)(IEventObjectCollection *This,BSTR objectID); + END_INTERFACE +} IEventObjectCollectionVtbl; +struct IEventObjectCollection { + CONST_VTBL struct IEventObjectCollectionVtbl *lpVtbl; +}; + + +typedef struct IEventSystem IEventSystem; + +const IID IID_IEventSystem; +typedef struct IEventSystemVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(IEventSystem *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(IEventSystem *This); + ULONG (WINAPI *Release)(IEventSystem *This); + HRESULT (WINAPI *GetTypeInfoCount)(IEventSystem *This,UINT *pctinfo); + HRESULT (WINAPI *GetTypeInfo)(IEventSystem *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo); + HRESULT (WINAPI *GetIDsOfNames)(IEventSystem *This,REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId); + HRESULT (WINAPI *Invoke)(IEventSystem *This,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr); + HRESULT (WINAPI *Query)(IEventSystem *This,BSTR progID,BSTR queryCriteria,int *errorIndex,IUnknown **ppInterface); + HRESULT (WINAPI *Store)(IEventSystem *This,BSTR ProgID,IUnknown *pInterface); + HRESULT (WINAPI *Remove)(IEventSystem *This,BSTR progID,BSTR queryCriteria,int *errorIndex); + HRESULT (WINAPI *get_EventObjectChangeEventClassID)(IEventSystem *This,BSTR *pbstrEventClassID); + HRESULT (WINAPI *QueryS)(IEventSystem *This,BSTR progID,BSTR queryCriteria,IUnknown **ppInterface); + HRESULT (WINAPI *RemoveS)(IEventSystem *This,BSTR progID,BSTR queryCriteria); + END_INTERFACE +} IEventSystemVtbl; +struct IEventSystem { + CONST_VTBL struct IEventSystemVtbl *lpVtbl; +}; + +typedef struct IEventSubscription IEventSubscription; + +const IID IID_IEventSubscription; +typedef struct IEventSubscriptionVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(IEventSubscription *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(IEventSubscription *This); + ULONG (WINAPI *Release)(IEventSubscription *This); + HRESULT (WINAPI *GetTypeInfoCount)(IEventSubscription *This,UINT *pctinfo); + HRESULT (WINAPI *GetTypeInfo)(IEventSubscription *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo); + HRESULT (WINAPI *GetIDsOfNames)(IEventSubscription *This,REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId); + HRESULT (WINAPI *Invoke)(IEventSubscription *This,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr); + HRESULT (WINAPI *get_SubscriptionID)(IEventSubscription *This,BSTR *pbstrSubscriptionID); + HRESULT (WINAPI *put_SubscriptionID)(IEventSubscription *This,BSTR bstrSubscriptionID); + HRESULT (WINAPI *get_SubscriptionName)(IEventSubscription *This,BSTR *pbstrSubscriptionName); + HRESULT (WINAPI *put_SubscriptionName)(IEventSubscription *This,BSTR bstrSubscriptionName); + HRESULT (WINAPI *get_PublisherID)(IEventSubscription *This,BSTR *pbstrPublisherID); + HRESULT (WINAPI *put_PublisherID)(IEventSubscription *This,BSTR bstrPublisherID); + HRESULT (WINAPI *get_EventClassID)(IEventSubscription *This,BSTR *pbstrEventClassID); + HRESULT (WINAPI *put_EventClassID)(IEventSubscription *This,BSTR bstrEventClassID); + HRESULT (WINAPI *get_MethodName)(IEventSubscription *This,BSTR *pbstrMethodName); + HRESULT (WINAPI *put_MethodName)(IEventSubscription *This,BSTR bstrMethodName); + HRESULT (WINAPI *get_SubscriberCLSID)(IEventSubscription *This,BSTR *pbstrSubscriberCLSID); + HRESULT (WINAPI *put_SubscriberCLSID)(IEventSubscription *This,BSTR bstrSubscriberCLSID); + HRESULT (WINAPI *get_SubscriberInterface)(IEventSubscription *This,IUnknown **ppSubscriberInterface); + HRESULT (WINAPI *put_SubscriberInterface)(IEventSubscription *This,IUnknown *pSubscriberInterface); + HRESULT (WINAPI *get_PerUser)(IEventSubscription *This,WINBOOL *pfPerUser); + HRESULT (WINAPI *put_PerUser)(IEventSubscription *This,WINBOOL fPerUser); + HRESULT (WINAPI *get_OwnerSID)(IEventSubscription *This,BSTR *pbstrOwnerSID); + HRESULT (WINAPI *put_OwnerSID)(IEventSubscription *This,BSTR bstrOwnerSID); + HRESULT (WINAPI *get_Enabled)(IEventSubscription *This,WINBOOL *pfEnabled); + HRESULT (WINAPI *put_Enabled)(IEventSubscription *This,WINBOOL fEnabled); + HRESULT (WINAPI *get_Description)(IEventSubscription *This,BSTR *pbstrDescription); + HRESULT (WINAPI *put_Description)(IEventSubscription *This,BSTR bstrDescription); + HRESULT (WINAPI *get_MachineName)(IEventSubscription *This,BSTR *pbstrMachineName); + HRESULT (WINAPI *put_MachineName)(IEventSubscription *This,BSTR bstrMachineName); + HRESULT (WINAPI *GetPublisherProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue); + HRESULT (WINAPI *PutPublisherProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue); + HRESULT (WINAPI *RemovePublisherProperty)(IEventSubscription *This,BSTR bstrPropertyName); + HRESULT (WINAPI *GetPublisherPropertyCollection)(IEventSubscription *This,IEventObjectCollection **collection); + HRESULT (WINAPI *GetSubscriberProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue); + HRESULT (WINAPI *PutSubscriberProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue); + HRESULT (WINAPI *RemoveSubscriberProperty)(IEventSubscription *This,BSTR bstrPropertyName); + HRESULT (WINAPI *GetSubscriberPropertyCollection)(IEventSubscription *This,IEventObjectCollection **collection); + HRESULT (WINAPI *get_InterfaceID)(IEventSubscription *This,BSTR *pbstrInterfaceID); + HRESULT (WINAPI *put_InterfaceID)(IEventSubscription *This,BSTR bstrInterfaceID); + END_INTERFACE +} IEventSubscriptionVtbl; +struct IEventSubscription { + CONST_VTBL struct IEventSubscriptionVtbl *lpVtbl; +}; + +#define PROGID_EventSubscription OLESTR("EventSystem.EventSubscription") + +#endif + +#ifdef HAVE_SENSEVTS_H +#include <sensevts.h> +#else + +/* Extract relevant typedefs from mingw-w64 headers */ + +typedef struct { + DWORD dwSize; + DWORD dwFlags; + DWORD dwOutSpeed; + DWORD dwInSpeed; +} *LPSENS_QOCINFO; + +typedef struct ISensNetwork ISensNetwork; + +const IID IID_ISensNetwork; +typedef struct ISensNetworkVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(ISensNetwork *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(ISensNetwork *This); + ULONG (WINAPI *Release)(ISensNetwork *This); + HRESULT (WINAPI *GetTypeInfoCount)(ISensNetwork *This,UINT *pctinfo); + HRESULT (WINAPI *GetTypeInfo)(ISensNetwork *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo); + HRESULT (WINAPI *GetIDsOfNames)(ISensNetwork *This,REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId); + HRESULT (WINAPI *Invoke)(ISensNetwork *This,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr); + HRESULT (WINAPI *ConnectionMade)(ISensNetwork *This,BSTR bstrConnection,ULONG ulType,LPSENS_QOCINFO lpQOCInfo); + HRESULT (WINAPI *ConnectionMadeNoQOCInfo)(ISensNetwork *This,BSTR bstrConnection,ULONG ulType); + HRESULT (WINAPI *ConnectionLost)(ISensNetwork *This,BSTR bstrConnection,ULONG ulType); + HRESULT (WINAPI *DestinationReachable)(ISensNetwork *This,BSTR bstrDestination,BSTR bstrConnection,ULONG ulType,LPSENS_QOCINFO lpQOCInfo); + HRESULT (WINAPI *DestinationReachableNoQOCInfo)(ISensNetwork *This,BSTR bstrDestination,BSTR bstrConnection,ULONG ulType); + END_INTERFACE +} ISensNetworkVtbl; +struct ISensNetwork { + CONST_VTBL struct ISensNetworkVtbl *lpVtbl; +}; + +#endif + +#include <shell/e-shell.h> +#include <e-util/e-extension.h> + +/* 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); + + +/* 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); +} + +/* Object to receive the ISensNetwork events */ + +typedef struct ESensNetworkListener { + ISensNetworkVtbl *lpVtbl; + long ref; + EWindowsSENS *ews_ptr; +} ESensNetworkListener; + +static void e_sens_network_listener_init(ESensNetworkListener**,EWindowsSENS*); + +/* Functions to implement ISensNetwork interface */ + +static HRESULT WINAPI e_sens_network_listener_queryinterface (ISensNetwork*,REFIID,void**); +static ULONG WINAPI e_sens_network_listener_addref (ISensNetwork*); +static ULONG WINAPI e_sens_network_listener_release (ISensNetwork*); +static HRESULT WINAPI e_sens_network_listener_gettypeinfocount (ISensNetwork*, UINT*); +static HRESULT WINAPI e_sens_network_listener_gettypeinfo (ISensNetwork*,UINT,LCID,ITypeInfo**); +static HRESULT WINAPI e_sens_network_listener_getidsofnames (ISensNetwork*,REFIID,LPOLESTR*,UINT,LCID, DISPID*); +static HRESULT WINAPI e_sens_network_listener_invoke (ISensNetwork*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*); +static HRESULT WINAPI e_sens_network_listener_connectionmade (ISensNetwork*,BSTR,ULONG,LPSENS_QOCINFO); +static HRESULT WINAPI e_sens_network_listener_connectionmadenoqocinfo (ISensNetwork*,BSTR,ULONG); +static HRESULT WINAPI e_sens_network_listener_connectionlost (ISensNetwork*,BSTR,ULONG); +static HRESULT WINAPI e_sens_network_listener_destinationreachable (ISensNetwork*,BSTR,BSTR,ULONG,LPSENS_QOCINFO); +static HRESULT WINAPI e_sens_network_listener_destinationreachablenoqocinfo (ISensNetwork*,BSTR,BSTR,ULONG); + +/* Initializing the VTable of our ESensNetworkListener object */ + +static ISensNetworkVtbl ESensNetworkListenerVtbl = { + e_sens_network_listener_queryinterface, + e_sens_network_listener_addref, + e_sens_network_listener_release, + e_sens_network_listener_gettypeinfocount, + e_sens_network_listener_gettypeinfo, + e_sens_network_listener_getidsofnames, + e_sens_network_listener_invoke, + e_sens_network_listener_connectionmade, + e_sens_network_listener_connectionmadenoqocinfo, + e_sens_network_listener_connectionlost, + e_sens_network_listener_destinationreachable, + e_sens_network_listener_destinationreachablenoqocinfo +}; + + +static HRESULT WINAPI +e_sens_network_listener_queryinterface (ISensNetwork *This, + REFIID iid, + void **ppv) +{ + if (IsEqualIID (iid, &IID_IUnknown) || IsEqualIID (iid, &IID_IDispatch) || IsEqualIID (iid, &IID_ISensNetwork)) { + *ppv = This; + ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv); + return S_OK; + } + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI +e_sens_network_listener_addref (ISensNetwork *This) +{ + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + return InterlockedIncrement(&(esnl_ptr->ref)); +} + +static ULONG WINAPI +e_sens_network_listener_release (ISensNetwork *This) +{ + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + ULONG tmp = InterlockedDecrement(&(esnl_ptr->ref)); + return tmp; +} + +static HRESULT WINAPI +e_sens_network_listener_gettypeinfocount (ISensNetwork *This, + UINT *pctinfo) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +e_sens_network_listener_gettypeinfo (ISensNetwork *This, + UINT iTInfo, + LCID lcid, + ITypeInfo **ppTInfo) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +e_sens_network_listener_getidsofnames (ISensNetwork *This, + REFIID riid, + LPOLESTR *rgszNames, + UINT cNames, + LCID lcid, + DISPID *rgDispId) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +e_sens_network_listener_invoke (ISensNetwork *This, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS *pDispParams, + VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, + UINT *puArgErr) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +e_sens_network_listener_connectionmade (ISensNetwork *This, + BSTR bstrConnection, + ULONG ulType, + LPSENS_QOCINFO lpQOCInfo) +{ + if (ulType) { + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + EShell *shell = windows_sens_get_shell (esnl_ptr->ews_ptr); + /* Wait a second so that the connection stabilizes */ + g_usleep(G_USEC_PER_SEC); + e_shell_set_network_available (shell, TRUE); + } + return S_OK; +} + +static HRESULT WINAPI +e_sens_network_listener_connectionmadenoqocinfo (ISensNetwork *This, + BSTR bstrConnection, + ULONG ulType) +{ + //Always followed by ConnectionMade + return S_OK; +} + +static HRESULT WINAPI +e_sens_network_listener_connectionlost (ISensNetwork *This, + BSTR bstrConnection, + ULONG ulType) +{ + if (ulType) { + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + EShell *shell = windows_sens_get_shell (esnl_ptr->ews_ptr); + e_shell_set_network_available (shell, FALSE); + } + return S_OK; +} + +static HRESULT WINAPI +e_sens_network_listener_destinationreachable (ISensNetwork *This, + BSTR bstrDestination, + BSTR bstrConnection, + ULONG ulType, + LPSENS_QOCINFO lpQOCInfo) +{ + if (ulType) { + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + EShell *shell = windows_sens_get_shell (esnl_ptr->ews_ptr); + /* Wait a second so that the connection stabilizes */ + g_usleep(G_USEC_PER_SEC); + e_shell_set_network_available (shell, TRUE); + } + return S_OK; +} + +static HRESULT WINAPI +e_sens_network_listener_destinationreachablenoqocinfo (ISensNetwork *This, + BSTR bstrDestination, + BSTR bstrConnection, + ULONG ulType) +{ + return S_OK; +} + +static void +e_sens_network_listener_init(ESensNetworkListener **esnl_ptr, + EWindowsSENS *ews) +{ + (*esnl_ptr) = g_new0(ESensNetworkListener,1); + (*esnl_ptr)->lpVtbl = &ESensNetworkListenerVtbl; + (*esnl_ptr)->ews_ptr = ews; + (*esnl_ptr)->ref = 1; +} + + +static BSTR +_mb2wchar (const char* a) +{ + static WCHAR b[64]; + MultiByteToWideChar (0, 0, a, -1, b, 64); + return b; +} + +static const char* add_curly_braces_to_uuid (const char* string_uuid) +{ + static char curly_braced_uuid_string[64]; + int i; + if (!string_uuid) + return NULL; + lstrcpy(curly_braced_uuid_string,"{"); + i = strlen(curly_braced_uuid_string); + lstrcat(curly_braced_uuid_string+i,string_uuid); + i = strlen(curly_braced_uuid_string); + lstrcat(curly_braced_uuid_string+i,"}"); + return curly_braced_uuid_string; +} + +static void +windows_sens_constructed (GObject *object) +{ + HRESULT res; + static IEventSystem *pEventSystem =0; + static IEventSubscription* pEventSubscription = 0; + static ESensNetworkListener *pESensNetworkListener = 0; + static const char* eventclassid="{D5978620-5B9F-11D1-8DD2-00AA004ABD5E}"; + static const char* methods[]={ + "ConnectionMade", + "ConnectionMadeNoQOCInfo", + "ConnectionLost", + "DestinationReachable", + "DestinationReachableNoQOCInfo" + }; + static const char* names[]={ + "EWS_ConnectionMade", + "EWS_ConnectionMadeNoQOCInfo", + "EWS_ConnectionLost", + "EWS_DestinationReachable", + "EWS_DestinationReachableNoQOCInfo" + }; + unsigned char* subids[] = { 0, 0, 0, 0, 0 }; + + EWindowsSENS *extension = (E_WINDOWS_SENS (object)); + e_sens_network_listener_init(&pESensNetworkListener, extension); + + CoInitialize(0); + + res=CoCreateInstance (&CLSID_CEventSystem, 0,CLSCTX_SERVER,&IID_IEventSystem,(LPVOID*)&pEventSystem); + + if (res == S_OK && pEventSystem) { + + unsigned i; + + for (i=0; i<G_N_ELEMENTS(methods); i++) { + + res=CoCreateInstance (&CLSID_CEventSubscription, 0, CLSCTX_SERVER, &IID_IEventSubscription, (LPVOID*)&pEventSubscription); + + if (res == S_OK && pEventSubscription) { + UUID tmp_uuid; + UuidCreate(&tmp_uuid); + UuidToString(&tmp_uuid, &subids[i]); + res=pEventSubscription->lpVtbl->put_SubscriptionID (pEventSubscription, _mb2wchar (add_curly_braces_to_uuid ((char*)subids[i]))); + if (res) { + RpcStringFree (&subids[i]); + break; + } + RpcStringFree (&subids[i]); + res=pEventSubscription->lpVtbl->put_SubscriptionName (pEventSubscription, _mb2wchar (names[i])); + if (res) + break; + res=pEventSubscription->lpVtbl->put_MethodName (pEventSubscription, _mb2wchar (methods[i])); + if (res) + break; + res=pEventSubscription->lpVtbl->put_EventClassID (pEventSubscription, _mb2wchar (eventclassid)); + if (res) + break; + res=pEventSubscription->lpVtbl->put_SubscriberInterface (pEventSubscription, (IUnknown*)pESensNetworkListener); + if (res) + break; + /* Make the subscription receive the event only if the owner of the subscription + * is logged on to the same computer as the publisher. This makes this module + * work with normal user account without administrative privileges. + */ + res=pEventSubscription->lpVtbl->put_PerUser (pEventSubscription, TRUE); + if (res) + break; + + res=pEventSystem->lpVtbl->Store (pEventSystem, (BSTR)PROGID_EventSubscription, (IUnknown*)pEventSubscription); + if (res) + break; + pEventSubscription->lpVtbl->Release (pEventSubscription); + pEventSubscription=0; + } + } + if (pEventSubscription) + pEventSubscription->lpVtbl->Release(pEventSubscription); + } + + /* Do not try to get initial state when we are sure we will not get system events. + * Like that we don't get stuck with Disconnected status if we were disconnected + * on start. + */ + if (res == S_OK) { + + typedef BOOL (WINAPI* IsNetworkAlive_t) (LPDWORD); + BOOL alive = TRUE; + EShell *shell = windows_sens_get_shell (extension); + + IsNetworkAlive_t pIsNetworkAlive = NULL; + + HMODULE hDLL=LoadLibrary ("sensapi.dll"); + + if ((pIsNetworkAlive=(IsNetworkAlive_t) GetProcAddress (hDLL, "IsNetworkAlive"))) { + DWORD Network; + alive=pIsNetworkAlive (&Network); + } + + FreeLibrary(hDLL); + + 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) +{ +} + +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) +{ +} + |