aboutsummaryrefslogtreecommitdiffstats
path: root/modules/windows-sens/evolution-windows-sens.c
diff options
context:
space:
mode:
authorFridrich Štrba <fridrich.strba@bluewin.ch>2010-03-26 23:58:26 +0800
committerFridrich Štrba <fridrich.strba@bluewin.ch>2010-03-27 04:45:35 +0800
commit56daae923f75506d49ff9677c7d629028925d9ef (patch)
tree083c706870103e904612bc56b1391e37033ee479 /modules/windows-sens/evolution-windows-sens.c
parent181b10d8b83b56fb53048af5a78b6be88f665ba3 (diff)
downloadgsoc2013-evolution-56daae923f75506d49ff9677c7d629028925d9ef.tar.gz
gsoc2013-evolution-56daae923f75506d49ff9677c7d629028925d9ef.tar.zst
gsoc2013-evolution-56daae923f75506d49ff9677c7d629028925d9ef.zip
[win32] Converting the Windows SENS from C++ to plain C
Diffstat (limited to 'modules/windows-sens/evolution-windows-sens.c')
-rw-r--r--modules/windows-sens/evolution-windows-sens.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/modules/windows-sens/evolution-windows-sens.c b/modules/windows-sens/evolution-windows-sens.c
new file mode 100644
index 0000000000..19fecc260b
--- /dev/null
+++ b/modules/windows-sens/evolution-windows-sens.c
@@ -0,0 +1,322 @@
+/*
+ * 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 <rpc.h>
+
+#include <shell/e-shell.h>
+#include <e-util/e-extension.h>
+
+#define NUM_ELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
+
+inline const 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 curlyBracedUuidString[64];
+ int i;
+ if (!stringUUID)
+ return NULL;
+ lstrcpy(curlyBracedUuidString,"{");
+ i = strlen(curlyBracedUuidString);
+ lstrcat(curlyBracedUuidString+i,stringUUID);
+ i = strlen(curlyBracedUuidString);
+ lstrcat(curlyBracedUuidString+i,"}");
+ return curlyBracedUuidString;
+}
+
+
+/* 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 e_sens_network_listener : public ISensNetwork
+{
+private:
+ long ref;
+ EWindowsSENS *mpEWS;
+
+public:
+ e_sens_network_listener (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;
+ }
+
+ virtual HRESULT WINAPI DestinationReachable (BSTR, 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 DestinationReachableNoQOCInfo (BSTR, BSTR, ULONG)
+ {
+ 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;
+ 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));
+ static e_sens_network_listener *pISensNetwork = new e_sens_network_listener (extension);
+
+ CoInitialize(0);
+
+ HRESULT res=CoCreateInstance (CLSID_CEventSystem, 0,CLSCTX_SERVER,IID_IEventSystem,(void**)&pIEventSystem);
+
+ if (res == S_OK && pIEventSystem) {
+
+ for (unsigned i=0; i<NUM_ELEMENTS(methods); i++) {
+
+ res=CoCreateInstance (CLSID_CEventSubscription, 0, CLSCTX_SERVER, IID_IEventSubscription, (LPVOID*)&pIEventSubscription);
+
+ if (res == S_OK && pIEventSubscription) {
+ UUID tmp_uuid;
+ UuidCreate(&tmp_uuid);
+ UuidToString(&tmp_uuid, &subids[i]);
+ if ((res=pIEventSubscription->put_SubscriptionID (_mb2wchar (add_curly_braces_to_uuid ((char*)subids[i]))))) {
+ RpcStringFree (&subids[i]);
+ break;
+ }
+ RpcStringFree (&subids[i]);
+ if ((res=pIEventSubscription->put_SubscriptionName (_mb2wchar (names[i]))))
+ break;
+ if ((res=pIEventSubscription->put_MethodName (_mb2wchar (methods[i]))))
+ break;
+ if ((res=pIEventSubscription->put_EventClassID (_mb2wchar (eventclassid))))
+ break;
+ if ((res=pIEventSubscription->put_SubscriberInterface ((IUnknown*)pISensNetwork)))
+ 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.
+ */
+ if ((res=pIEventSubscription->put_PerUser (TRUE)))
+ break;
+
+ if ((res=pIEventSystem->Store ((BSTR)PROGID_EventSubscription, (IUnknown*)pIEventSubscription)))
+ break;
+ pIEventSubscription->Release ();
+ pIEventSubscription=0;
+ }
+ }
+ if (pIEventSubscription)
+ pIEventSubscription->Release();
+ }
+
+ /* 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);
+
+ 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)
+{
+}
+
+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