[git] GpgOL - branch, mime-addin, created. gpgol-1.2.0-20-gcb6c248

by Andre Heinecke cvs at cvs.gnupg.org
Wed Sep 16 15:35:41 CEST 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG extension for MS Outlook".

The branch, mime-addin has been created
        at  cb6c248aed297d8240b152b8f49554c48a380ef7 (commit)

- Log -----------------------------------------------------------------
commit cb6c248aed297d8240b152b8f49554c48a380ef7
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Sep 16 15:26:00 2015 +0200

    Add support for MIME encryption / signing
    
    This currently tries to encrypt / sign all mails sent.
    
    * src/eventsinks.cpp (MailItemEvents::Invoke): Sign/Encrypt
      mails in AfterWrite event.
    
    --
    Before this I tried using the Application's ItemSend event and
    the Send / Write event's of the MailItem. In the ItemSend
    event you can't access the SecureItem interface and the
    MAPIObject is not filled.
    
    In Send / Write get_oom_base_message works but again
    the relevant values are not set. Only AfterWrite gives
    us access to the filled MAPI Object but in case of errors
    we don't have a cancel parameter here anymore to
    abort sending the mail. So this might not be the best
    event for this.

diff --git a/src/eventsinks.cpp b/src/eventsinks.cpp
index ecf6285..de91206 100644
--- a/src/eventsinks.cpp
+++ b/src/eventsinks.cpp
@@ -164,6 +164,32 @@ EVENT_SINK_INVOKE(MailItemEvents)
         {
           break;
         }
+      case AfterWrite:
+        {
+          LPMESSAGE message = get_oom_base_message (m_object);
+          if (message)
+            {
+              int ret;
+              log_debug ("%s:%s: Sign / Encrypting message",
+                         SRCNAME, __func__);
+              ret = message_sign_encrypt (message, PROTOCOL_UNKNOWN, NULL);
+              log_debug ("%s:%s: Sign / Encryption status: %i",
+                         SRCNAME, __func__, ret);
+              message->Release ();
+              if (ret)
+                {
+                  // VARIANT_BOOL *cancel = parms->rgvarg[0].pboolVal;
+                  // *cancel = VARIANT_TRUE;
+                  /* TODO inform the user that sending was canceled */
+                }
+            }
+          else
+            {
+              log_error ("%s:%s: Failed to get base message.",
+                         SRCNAME, __func__);
+              break;
+            }
+        }
       default:
         log_debug ("%s:%s: Unhandled Event: %lx \n",
                        SRCNAME, __func__, dispid);

commit b4e52ecfd4e62a0d3cb571e5dc72e19fbfcdccae
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Sep 16 15:24:28 2015 +0200

    Simplify ReadEvent handling
    
    * src/eventsinks.cpp (MailItemEvents::Invoke): Use
      get_oom_base_message instead of doing this here.

diff --git a/src/eventsinks.cpp b/src/eventsinks.cpp
index 4335e3d..ecf6285 100644
--- a/src/eventsinks.cpp
+++ b/src/eventsinks.cpp
@@ -147,52 +147,17 @@ EVENT_SINK_INVOKE(MailItemEvents)
     {
       case BeforeRead:
         {
-          LPUNKNOWN mailItem = NULL;
-          HRESULT hr;
-          LPDISPATCH secureItem = NULL;
-          LPMESSAGE message = NULL;
-          LPMAPISECUREMESSAGE secureMessage = NULL;
-
-          mailItem = get_oom_iunknown (m_object, "MapiObject");
-          if (!mailItem)
-            {
-              log_error ("%s:%s: Failed to obtain MailItem.",
-                         SRCNAME, __func__);
-            }
-
-          secureItem = get_object_by_id ((LPDISPATCH)mailItem,
-                                         IID_IMAPISecureMessage);
-          if (!secureItem)
-            {
-              log_error ("%s:%s: Failed to obtain SecureItem.",
-                         SRCNAME, __func__);
-              mailItem->Release();
-              break;
-            }
-
-          secureMessage = (LPMAPISECUREMESSAGE) secureItem;
-
-          /* The call to GetBaseMessage is pretty much a jump
-             in the dark. So it would not be surprising to get
-             crashes here in the future. */
-          log_oom_extra("%s:%s: About to call GetBaseMessage.",
-                        SRCNAME, __func__);
-          hr = secureMessage->GetBaseMessage (&message);
-          if ( hr == S_OK)
+          LPMESSAGE message = get_oom_base_message (m_object);
+          if (message)
             {
               int ret;
               log_oom_extra ("%s:%s: GetBaseMessage OK.",
                              SRCNAME, __func__);
-              ret = message_incoming_handler(message, NULL, false);
+              ret = message_incoming_handler (message, NULL, false);
               log_debug ("%s:%s: incoming handler status: %i",
                          SRCNAME, __func__, ret);
+              message->Release ();
             }
-          else
-            {
-              log_error_w32 (hr, "Failed to GetBaseMessage.");
-            }
-          secureMessage->Release ();
-          mailItem->Release ();
           break;
         }
       case ReadComplete:
@@ -200,7 +165,7 @@ EVENT_SINK_INVOKE(MailItemEvents)
           break;
         }
       default:
-        log_oom_extra ("%s:%s: Unhandled Event: %lx \n",
+        log_debug ("%s:%s: Unhandled Event: %lx \n",
                        SRCNAME, __func__, dispid);
     }
   return S_OK;

commit f5689fdafa7bab95633faebf3a25f36f234bc8c1
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Sep 16 15:20:37 2015 +0200

    Add get_oom_base_message helper function.
    
    * src/oomhelp.cpp (get_oom_base_message): New. Extract base message
      from MessageItem Object.
    * src/oomhelp.h (get_oom_base_message): Declare.

diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
index 4df3eda..08db412 100644
--- a/src/oomhelp.cpp
+++ b/src/oomhelp.cpp
@@ -1002,3 +1002,48 @@ get_object_by_id (LPDISPATCH pDisp, REFIID id)
     return NULL;
   return disp;
 }
+
+LPMESSAGE
+get_oom_base_message (LPDISPATCH pDisp)
+{
+  HRESULT hr;
+  LPDISPATCH secureItem = NULL;
+  LPUNKNOWN mapiObject = NULL;
+  LPMESSAGE message = NULL;
+  LPMAPISECUREMESSAGE secureMessage = NULL;
+
+  mapiObject = get_oom_iunknown (pDisp, "MapiObject");
+  if (!mapiObject)
+    {
+      log_error ("%s:%s: Failed to obtain MailItem.",
+                 SRCNAME, __func__);
+      return NULL;
+    }
+
+  secureItem = get_object_by_id ((LPDISPATCH) mapiObject,
+                                 IID_IMAPISecureMessage);
+  mapiObject->Release ();
+  if (!secureItem)
+    {
+      log_error ("%s:%s: Failed to obtain SecureItem.",
+                 SRCNAME, __func__);
+      return NULL;
+    }
+
+  secureMessage = (LPMAPISECUREMESSAGE) secureItem;
+
+  /* The call to GetBaseMessage is pretty much a jump
+     in the dark. So it would not be surprising to get
+     crashes here in the future. */
+  log_oom_extra("%s:%s: About to call GetBaseMessage.",
+                SRCNAME, __func__);
+  hr = secureMessage->GetBaseMessage (&message);
+  secureMessage->Release ();
+  if (hr != S_OK)
+    {
+      log_error_w32 (hr, "Failed to GetBaseMessage.");
+      return NULL;
+    }
+
+  return message;
+}
diff --git a/src/oomhelp.h b/src/oomhelp.h
index 3aca523..69df878 100644
--- a/src/oomhelp.h
+++ b/src/oomhelp.h
@@ -22,6 +22,7 @@
 #define OOMHELP_H
 
 #include <unknwn.h>
+#include "mymapi.h"
 
 /* Helper to release dispatcher */
 #define RELDISP(dispatcher) if (dispatcher) dispatcher->Release()
@@ -152,6 +153,16 @@ get_pa_string (LPDISPATCH pDisp, const char *property);
 LPDISPATCH
 get_object_by_id (LPDISPATCH pDisp, REFIID id);
 
+/* Obtain the Base MAPI Message of a MailItem.
+   The parameter should be a pointer to a MailItem.
+   returns NULL on error.
+
+   The returned Message needs to be released by the
+   caller.
+*/
+LPMESSAGE
+get_oom_base_message (LPDISPATCH mailItem);
+
 #ifdef __cplusplus
 }
 #endif

commit c4133613ddf6ded619226eb46f78d585ee25a538
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Sep 16 15:19:22 2015 +0200

    Add MailItem Event dispids
    
    * src/eventsinks.cpp (MailItemEvents::MailItemEvent): Add dispids
     for other events.

diff --git a/src/eventsinks.cpp b/src/eventsinks.cpp
index 569c0f3..4335e3d 100644
--- a/src/eventsinks.cpp
+++ b/src/eventsinks.cpp
@@ -112,33 +112,32 @@ EVENT_SINK_DEFAULT_CTOR(MailItemEvents)
 EVENT_SINK_DEFAULT_DTOR(MailItemEvents)
 typedef enum
   {
-    /* TODO add dispids. */
-    AfterWrite,
-    AttachmentAdd,
-    AttachmentRead,
-    AttachmentRemove,
-    BeforeAttachmentAdd,
-    BeforeAttachmentPreview,
-    BeforeAttachmentRead,
-    BeforeAttachmentSave,
-    BeforeAttachmentWriteToTempFile,
-    BeforeAutoSave,
-    BeforeCheckNames,
-    BeforeDelete,
+    AfterWrite = 0xFC8D,
+    AttachmentAdd = 0xF00B,
+    AttachmentRead = 0xF00C,
+    AttachmentRemove = 0xFBAE,
+    BeforeAttachmentAdd = 0xFBB0,
+    BeforeAttachmentPreview = 0xFBAF,
+    BeforeAttachmentRead = 0xFBAB,
+    BeforeAttachmentSave = 0xF00D,
+    BeforeAttachmentWriteToTempFile = 0xFBB2,
+    BeforeAutoSave = 0xFC02,
+    BeforeCheckNames = 0xF00A,
+    BeforeDelete = 0xFA75,
     BeforeRead = 0xFC8C,
-    Close,
-    CustomAction,
-    CustomPropertyChange,
-    Forward,
-    Open,
-    PropertyChange,
-    Read,
+    Close = 0xF004,
+    CustomAction = 0xF006,
+    CustomPropertyChange = 0xF008,
+    Forward = 0xF468,
+    Open = 0xF003,
+    PropertyChange = 0xF009,
+    Read = 0xF001,
     ReadComplete = 0xFC8F,
-    Reply,
-    ReplyAll,
-    Send,
-    Unload,
-    Write
+    Reply = 0xFC8F,
+    ReplyAll = 0xF467,
+    Send = 0xF005,
+    Unload = 0xFBAD,
+    Write = 0xF002
   } MailEvent;
 
 EVENT_SINK_INVOKE(MailItemEvents)

commit 9e1a2bcddd28a16aadf86c6dd11e02c70411198e
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Sep 16 15:15:51 2015 +0200

    Check parameter type in ItemLoad event.
    
    * src/eventsinks.cpp (ApplicationEvents::Invoke): Check parameter
      type before using it.

diff --git a/src/eventsinks.cpp b/src/eventsinks.cpp
index dffe246..569c0f3 100644
--- a/src/eventsinks.cpp
+++ b/src/eventsinks.cpp
@@ -66,12 +66,14 @@ EVENT_SINK_INVOKE(ApplicationEvents)
         {
           LPDISPATCH mailItem;
           LPDISPATCH mailEventSink;
-          if (parms->cArgs == 0)
+          /* The mailItem should be the first argument */
+          if (parms->cArgs != 1 || parms->rgvarg[0].vt != VT_DISPATCH)
             {
-              log_error ("%s:%s: Itemload without arguments.",
+              log_error ("%s:%s: ItemLoad with unexpected Arguments.",
                          SRCNAME, __func__);
               break;
             }
+
           mailItem = get_object_by_id (parms->rgvarg[0].pdispVal,
                                        IID_MailItem);
           if (!mailItem)

commit 85e426b2905d077350353110c6f49143a1184a19
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Wed Sep 16 10:38:47 2015 +0200

    Add framework for mime decrypt / verify
    
    Add event handling for Application and MailItem
    events and use the message incoming handler in
    the before read event.
    
    * src/comhelp.h: Removed again. Macros moved to mymapi.h where
      they are better placed.
    * src/eventsink.h: (EVENT_SINK_DEFAULT_DTOR_CODE): Release /
      unadvise properly.
      (USE_INVOKE_ARGS): New. Used to avoid unused parameter
      warnings.
      (debug_oom, debug_oom_extra): Moved to util.h.
    * src/eventsinks.h: New. Header to declare event sink install /
      detach functions.
    * src/eventsinks.cpp: New. Event sinks for MailItem and Application.
    * src/oomhelp.h: Define GUID's necessary for the Event handlers.
      (get_object_by_id): New. oomhelp API style wrapper around
      QueryInterface.
    * src/oomhelp.cpp (get_object_by_id): New.
    * src/util.h (log_oom, log_oom_extra): New. Logging helper.
    * src/mymapi.h: Add Macros from comhelp.
      (IMAPISecureMessage): Declare COM interface.
    * src/message.h: Add headers that were indirectly included
      in other usages.
    * src/gpgoladdin.h (GpgolAddin): Add Application Event sink member.
    * src/gpgoladdin.cpp (OnStartupComplete): Install Application Event
      sink.
    
    --
    
    This establishes the framework for proper MIME handling
    currently mails are decrypted / verified but the message
    content is not yet shown in Outlook.
    
    The ApplicationEvent sink handles ItemLoad events (which should
    happen once a Message is loaded into Outlook) and uses the event
    to connect a MailItemEvent handler to the MailItem. The
    MailItemEvent handler then handles the BeforeRead event and

diff --git a/src/Makefile.am b/src/Makefile.am
index 59ba6cf..b7c4046 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -88,7 +88,8 @@ gpgol_SOURCES = \
 	gpgoladdin.cpp gpgoladdin.h \
 	ribbon-callbacks.cpp ribbon-callbacks.h \
 	parsetlv.c parsetlv.h \
-	filetype.c filetype.h
+	filetype.c filetype.h \
+	eventsinks.h eventsinks.cpp
 
 
 #treeview_SOURCES = treeview.c
diff --git a/src/comhelp.h b/src/comhelp.h
deleted file mode 100644
index 073c85b..0000000
--- a/src/comhelp.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* comhelp.h - Helper macros to define / declare COM interfaces.
- *    Copyright (C) 2015 Intevation GmbH
- *
- * This file is part of GpgOL.
- *
- * GpgOL 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.1 of the License, or (at your option) any later version.
- *
- * GpgOL 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 this program; if not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef COMHELP_H
-#define COMHELP_H
-
-/*** IUnknown methods ***/
-#define DECLARE_IUNKNOWN_METHODS                        \
-  STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID*) PURE; \
-  STDMETHOD_(ULONG,AddRef)(THIS) PURE;                  \
-  STDMETHOD_(ULONG,Release)(THIS) PURE
-
-/*** IDispatch methods ***/
-#define DECLARE_IDISPATCH_METHODS                                             \
-  STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE;                              \
-  STDMETHOD(GetTypeInfo)(THIS_ UINT, LCID, LPTYPEINFO*) PURE;                 \
-  STDMETHOD(GetIDsOfNames)(THIS_ REFIID, LPOLESTR*, UINT, LCID, DISPID*) PURE;\
-  STDMETHOD(Invoke)(THIS_ DISPID, REFIID, LCID, WORD,                         \
-                    DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*) PURE
-
-#endif // COMHELP_H
diff --git a/src/eventsink.h b/src/eventsink.h
index f94793b..4886d65 100644
--- a/src/eventsink.h
+++ b/src/eventsink.h
@@ -1,5 +1,6 @@
 /* eventsink.h - Macros to implement an OLE event sink
- *	Copyright (C) 2009 g10 Code GmbH
+ *     Copyright (C) 2009 g10 Code GmbH
+ *     Copyright (C) 2015 Intevation GmbH
  *
  * This file is part of GpgOL.
  *
@@ -21,12 +22,11 @@
    for our purpose but far from optimal; e.g. we should not simply
    provide stubs but do real sub-classing by modifying the vtables.  */
 
+/* See eventsinks.cpp for example usage */
+
 #ifndef EVENTSINK_H
 #define EVENTSINK_H
 
-#define debug_oom        (opt.enable_debug & DBG_OOM)
-#define debug_oom_extra  (opt.enable_debug & DBG_OOM_EXTRA)
-
 
 #define BEGIN_EVENT_SINK(subcls,parentcls)                               \
 class subcls : public parentcls                                          \
@@ -84,14 +84,19 @@ STDMETHODIMP subcls::Invoke (DISPID dispid, REFIID riid, LCID lcid,      \
                 EXCEPINFO *exepinfo, UINT *argerr)                       \
 /* End of macro EVENT_SINK_INVOKE.  */
 
+#define USE_INVOKE_ARGS                                                  \
+  (void)riid; (void)lcid; (void) flags; (void)parms; (void)result;       \
+  (void)exepinfo; (void)argerr;
+/* End of macro USE_INVOKE_ARGS. */
+
 #define EVENT_SINK_DEFAULT_DTOR_CODE(subcls)                             \
 {                                                                        \
   if (debug_oom)                                                         \
     log_debug ("%s:" #subcls ":%s: tdor", SRCNAME, __func__);            \
   if (m_pCP)                                                             \
-    log_error ("%s:%s: Unadvise missing", SRCNAME, __func__);            \
+    m_pCP->Unadvise(m_cookie);                                           \
   if (m_object)                                                          \
-    log_error ("%s:%s: Object not released", SRCNAME,__func__);          \
+    m_object->Release();                                                 \
 }                                                                        \
 /* End of macro EVENT_SINK_DTOR_DEFAULT_CODE.  */
 
diff --git a/src/eventsinks.cpp b/src/eventsinks.cpp
new file mode 100644
index 0000000..dffe246
--- /dev/null
+++ b/src/eventsinks.cpp
@@ -0,0 +1,207 @@
+/* eventsinks.cpp - Event handling classes.
+ *    Copyright (C) 2015 Intevation GmbH
+ *
+ * This file is part of GpgOL.
+ *
+ * GpgOL 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.1 of the License, or (at your option) any later version.
+ *
+ * GpgOL 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 this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* The event handler classes defined in this file follow the
+   general pattern that they implment the IDispatch interface
+   through the eventsink macros and handle event invocations
+   in their invoke methods.
+*/
+#include "eventsink.h"
+#include "eventsinks.h"
+#include "ocidl.h"
+#include "common.h"
+#include "oomhelp.h"
+#include "mymapi.h"
+#include "message.h"
+
+/* Application Events */
+BEGIN_EVENT_SINK(ApplicationEvents, IDispatch)
+EVENT_SINK_DEFAULT_CTOR(ApplicationEvents)
+EVENT_SINK_DEFAULT_DTOR(ApplicationEvents)
+typedef enum
+  {
+    AdvancedSearchComplete = 0xFA6A,
+    AdvancedSearchStopped = 0xFA6B,
+    AttachmentContextMenuDisplay = 0xFB3E,
+    BeforeFolderSharingDialog = 0xFC01,
+    ContextMenuClose = 0xFBA6,
+    FolderContextMenuDisplay = 0xFB42,
+    ItemContextMenuDisplay = 0xFB41,
+    ItemLoad = 0xFBA7,
+    ItemSend = 0xF002,
+    MAPILogonComplete = 0xFA90,
+    NewMail = 0xF003,
+    NewMailEx = 0xFAB5,
+    OptionsPagesAdd = 0xF005,
+    Quit = 0xF007,
+    Reminder = 0xF004,
+    ShortcutContextMenuDisplay = 0xFB44,
+    Startup = 0xF006,
+    StoreContextMenuDisplay = 0xFB43,
+    ViewContextMenuDisplay = 0xFB40
+  } ApplicationEvent;
+
+EVENT_SINK_INVOKE(ApplicationEvents)
+{
+  USE_INVOKE_ARGS
+  switch(dispid)
+    {
+      case ItemLoad:
+        {
+          LPDISPATCH mailItem;
+          LPDISPATCH mailEventSink;
+          if (parms->cArgs == 0)
+            {
+              log_error ("%s:%s: Itemload without arguments.",
+                         SRCNAME, __func__);
+              break;
+            }
+          mailItem = get_object_by_id (parms->rgvarg[0].pdispVal,
+                                       IID_MailItem);
+          if (!mailItem)
+            {
+              log_error ("%s:%s: ItemLoad event without mailitem.",
+                         SRCNAME, __func__);
+              break;
+            }
+          mailEventSink = install_MailItemEvents_sink (mailItem);
+          /* TODO figure out what we need to do with the event sink.
+             Does it need to be Released at some point? What happens
+             on unload? */
+          if (!mailEventSink)
+            {
+              log_error ("%s:%s: Failed to install MailItemEvents sink.",
+                         SRCNAME, __func__);
+            }
+          mailItem->Release ();
+          break;
+        }
+      default:
+        log_oom_extra ("%s:%s: Unhandled Event: %lx \n",
+                       SRCNAME, __func__, dispid);
+    }
+  /* We always return S_OK even on error so that outlook
+     continues to handle the event and is not disturbed
+     by our errors. There shouldn't be errors in here
+     anyway if everything works as documented. */
+  return S_OK;
+}
+END_EVENT_SINK(ApplicationEvents, IID_ApplicationEvents)
+
+/* Mail Item Events */
+BEGIN_EVENT_SINK(MailItemEvents, IDispatch)
+EVENT_SINK_DEFAULT_CTOR(MailItemEvents)
+EVENT_SINK_DEFAULT_DTOR(MailItemEvents)
+typedef enum
+  {
+    /* TODO add dispids. */
+    AfterWrite,
+    AttachmentAdd,
+    AttachmentRead,
+    AttachmentRemove,
+    BeforeAttachmentAdd,
+    BeforeAttachmentPreview,
+    BeforeAttachmentRead,
+    BeforeAttachmentSave,
+    BeforeAttachmentWriteToTempFile,
+    BeforeAutoSave,
+    BeforeCheckNames,
+    BeforeDelete,
+    BeforeRead = 0xFC8C,
+    Close,
+    CustomAction,
+    CustomPropertyChange,
+    Forward,
+    Open,
+    PropertyChange,
+    Read,
+    ReadComplete = 0xFC8F,
+    Reply,
+    ReplyAll,
+    Send,
+    Unload,
+    Write
+  } MailEvent;
+
+EVENT_SINK_INVOKE(MailItemEvents)
+{
+  USE_INVOKE_ARGS
+  switch(dispid)
+    {
+      case BeforeRead:
+        {
+          LPUNKNOWN mailItem = NULL;
+          HRESULT hr;
+          LPDISPATCH secureItem = NULL;
+          LPMESSAGE message = NULL;
+          LPMAPISECUREMESSAGE secureMessage = NULL;
+
+          mailItem = get_oom_iunknown (m_object, "MapiObject");
+          if (!mailItem)
+            {
+              log_error ("%s:%s: Failed to obtain MailItem.",
+                         SRCNAME, __func__);
+            }
+
+          secureItem = get_object_by_id ((LPDISPATCH)mailItem,
+                                         IID_IMAPISecureMessage);
+          if (!secureItem)
+            {
+              log_error ("%s:%s: Failed to obtain SecureItem.",
+                         SRCNAME, __func__);
+              mailItem->Release();
+              break;
+            }
+
+          secureMessage = (LPMAPISECUREMESSAGE) secureItem;
+
+          /* The call to GetBaseMessage is pretty much a jump
+             in the dark. So it would not be surprising to get
+             crashes here in the future. */
+          log_oom_extra("%s:%s: About to call GetBaseMessage.",
+                        SRCNAME, __func__);
+          hr = secureMessage->GetBaseMessage (&message);
+          if ( hr == S_OK)
+            {
+              int ret;
+              log_oom_extra ("%s:%s: GetBaseMessage OK.",
+                             SRCNAME, __func__);
+              ret = message_incoming_handler(message, NULL, false);
+              log_debug ("%s:%s: incoming handler status: %i",
+                         SRCNAME, __func__, ret);
+            }
+          else
+            {
+              log_error_w32 (hr, "Failed to GetBaseMessage.");
+            }
+          secureMessage->Release ();
+          mailItem->Release ();
+          break;
+        }
+      case ReadComplete:
+        {
+          break;
+        }
+      default:
+        log_oom_extra ("%s:%s: Unhandled Event: %lx \n",
+                       SRCNAME, __func__, dispid);
+    }
+  return S_OK;
+}
+END_EVENT_SINK(MailItemEvents, IID_MailItemEvents)
diff --git a/src/eventsinks.h b/src/eventsinks.h
new file mode 100644
index 0000000..0bcfc03
--- /dev/null
+++ b/src/eventsinks.h
@@ -0,0 +1,28 @@
+/* eventsinks.h - Declaraion of eventsink installation functions.
+ *    Copyright (C) 2015 Intevation GmbH
+ *
+ * This file is part of GpgOL.
+ *
+ * GpgOL 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.1 of the License, or (at your option) any later version.
+ *
+ * GpgOL 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 this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef EVENTSINKS_H
+#define EVENTSINKS_H
+
+#include <windows.h>
+
+LPDISPATCH install_ApplicationEvents_sink (LPDISPATCH obj);
+void detach_ApplicationEvents_sink (LPDISPATCH obj);
+LPDISPATCH install_MailItemEvents_sink (LPDISPATCH obj);
+void detach_MailItemEvents_sink (LPDISPATCH obj);
+#endif // EVENTSINKS_H
diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp
index 9c15fe5..7323674 100644
--- a/src/gpgoladdin.cpp
+++ b/src/gpgoladdin.cpp
@@ -45,6 +45,7 @@
 
 #include "gpgol-ids.h"
 #include "ribbon-callbacks.h"
+#include "eventsinks.h"
 
 #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \
                                      SRCNAME, __func__, __LINE__); \
@@ -148,7 +149,7 @@ STDMETHODIMP GpgolAddinFactory::CreateInstance (LPUNKNOWN punk, REFIID riid,
    The ref count is set by the factory after creation.
 */
 GpgolAddin::GpgolAddin (void) : m_lRef(0), m_application(0),
-  m_addin(0), m_disabled(false)
+  m_addin(0), m_applicationEventSink(0), m_disabled(false)
 {
   read_options ();
   /* RibbonExtender is it's own object to avoid the pitfalls of
@@ -163,6 +164,7 @@ GpgolAddin::~GpgolAddin (void)
              SRCNAME, __func__);
 
   delete m_ribbonExtender;
+  delete m_applicationEventSink;
 
   if (!m_disabled)
     {
@@ -276,12 +278,7 @@ GpgolAddin::OnStartupComplete (SAFEARRAY** custom)
 
   if (m_application)
     {
-      /*
-         An install_sinks here works this but we
-         don't implement all the old extension feature
-         in the addin yet.
-         install_sinks ((LPEXCHEXTCALLBACK)m_application);
-      */
+      m_applicationEventSink = install_ApplicationEvents_sink(m_application);
       return S_OK;
     }
   /* Should not happen as OnConnection should be called before */
diff --git a/src/gpgoladdin.h b/src/gpgoladdin.h
index 754765d..7b0c29a 100644
--- a/src/gpgoladdin.h
+++ b/src/gpgoladdin.h
@@ -22,10 +22,10 @@
 
 #include <windows.h>
 
-#include "comhelp.h"
+#include "mymapi.h"
 
 class GpgolAddinRibbonExt;
-class GpgolExt;
+class ApplicationEventListener;
 
 /* Enums for the IDTExtensibility2 interface*/
 typedef enum
@@ -205,6 +205,7 @@ private:
 
   LPDISPATCH m_application;
   LPDISPATCH m_addin;
+  LPDISPATCH m_applicationEventSink;
   bool m_disabled;
 
 };
diff --git a/src/message.h b/src/message.h
index 4b46139..7331e99 100644
--- a/src/message.h
+++ b/src/message.h
@@ -20,6 +20,8 @@
 #ifndef MESSAGE_H
 #define MESSAGE_H
 
+#include "myexchext.h"
+#include "mapihelp.h"
 
 int message_incoming_handler (LPMESSAGE message, HWND hwnd, bool force);
 bool message_display_handler (LPMESSAGE message, LPDISPATCH inspector, 
diff --git a/src/mymapi.h b/src/mymapi.h
index f3ca441..4be28c3 100644
--- a/src/mymapi.h
+++ b/src/mymapi.h
@@ -2,6 +2,7 @@
  * Copyright (C) 1998 Justin Bradford
  * Copyright (C) 2000 François Gouget
  * Copyright (C) 2005, 2007 g10 Code GmbH
+ * Copyright (C) 2015 Intevation GmbH
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -38,8 +39,6 @@
 #ifndef MAPI_H
 #define MAPI_H
 
-#include "comhelp.h"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -872,6 +871,22 @@ typedef struct IMAPIFormContainer *LPMAPIFORMCONTAINER;
                              LPMDB mdb, ULONG FAR *r_flags,                   \
                              ULONG FAR *n_entryid, LPBYTE FAR *entryid) PURE
 
+/* In difference to the MY_ macros the DECLARE_ macros are not undefined
+   in this header. */
+
+/*** IUnknown methods ***/
+#define DECLARE_IUNKNOWN_METHODS                                              \
+  STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID*) PURE;                       \
+  STDMETHOD_(ULONG,AddRef)(THIS) PURE;                                        \
+  STDMETHOD_(ULONG,Release)(THIS) PURE
+
+/*** IDispatch methods ***/
+#define DECLARE_IDISPATCH_METHODS                                             \
+  STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE;                              \
+  STDMETHOD(GetTypeInfo)(THIS_ UINT, LCID, LPTYPEINFO*) PURE;                 \
+  STDMETHOD(GetIDsOfNames)(THIS_ REFIID, LPOLESTR*, UINT, LCID, DISPID*) PURE;\
+  STDMETHOD(Invoke)(THIS_ DISPID, REFIID, LCID, WORD,                         \
+                    DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*) PURE
 
 
 
@@ -1165,6 +1180,24 @@ HRESULT WINAPI OpenStreamOnFile(LPALLOCATEBUFFER,LPFREEBUFFER,
                                 ULONG,LPSTR,LPSTR,LPSTREAM*);
 #endif
 
+/* IMAPISecureMessage */
+struct IMAPISecureMessage;
+typedef struct IMAPISecureMessage *LPMAPISECUREMESSAGE;
+
+#undef INTERFACE
+#define INTERFACE IMAPISecureMessage
+
+DECLARE_INTERFACE_(IMAPISecureMessage, IUnknown)
+{
+  DECLARE_IUNKNOWN_METHODS;
+
+  STDMETHOD(Unknown1)(void) PURE;
+  STDMETHOD(Unknown2)(void) PURE;
+  STDMETHOD(Unknown3)(void) PURE;
+  STDMETHOD(Unknown4)(void) PURE;
+  STDMETHOD(Unknown5)(void) PURE;
+  STDMETHOD(GetBaseMessage)(LPMESSAGE FAR *) PURE;
+};
 
 STDAPI MAPIOpenLocalFormContainer (LPMAPIFORMCONTAINER FAR *ppfcnt);
 
diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
index ccc389b..4df3eda 100644
--- a/src/oomhelp.cpp
+++ b/src/oomhelp.cpp
@@ -1,5 +1,6 @@
 /* oomhelp.cpp - Helper functions for the Outlook Object Model
  *	Copyright (C) 2009 g10 Code GmbH
+ *	Copyright (C) 2015 Intevation GmbH
  * 
  * This file is part of GpgOL.
  * 
@@ -988,3 +989,16 @@ add_oom_attachment (LPDISPATCH disp, wchar_t* inFileW)
 
   return hr == S_OK ? 0 : -1;
 }
+
+LPDISPATCH
+get_object_by_id (LPDISPATCH pDisp, REFIID id)
+{
+  LPDISPATCH disp = NULL;
+
+  if (!pDisp)
+    return NULL;
+
+  if (pDisp->QueryInterface (id, (void **)&disp) != S_OK)
+    return NULL;
+  return disp;
+}
diff --git a/src/oomhelp.h b/src/oomhelp.h
index 5c11797..3aca523 100644
--- a/src/oomhelp.h
+++ b/src/oomhelp.h
@@ -1,6 +1,7 @@
 /* oomhelp.h - Defs for helper functions for the Outlook Object Model
- *	Copyright (C) 2009 g10 Code GmbH
- * 
+ *     Copyright (C) 2009 g10 Code GmbH
+ *     Copyright (C) 2015 Intevation GmbH
+ *
  * This file is part of GpgOL.
  * 
  * GpgOL is free software; you can redistribute it and/or
@@ -62,6 +63,14 @@ DEFINE_GUID(IID_IConnectionPointContainer,
 DEFINE_GUID(IID_IPictureDisp,
             0x7bf80981, 0xbf32, 0x101a,
             0x8b, 0xbb, 0x00, 0xaa, 0x00, 0x30, 0x0c, 0xab);
+DEFINE_GUID(IID_ApplicationEvents, 0x0006304E, 0x0000, 0x0000,
+            0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+DEFINE_GUID(IID_MailItemEvents, 0x0006302B, 0x0000, 0x0000,
+            0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+DEFINE_GUID(IID_MailItem, 0x00063034, 0x0000, 0x0000,
+            0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+DEFINE_GUID(IID_IMAPISecureMessage, 0x253cc320, 0xeab6, 0x11d0,
+            0x82, 0x22, 0, 0x60, 0x97, 0x93, 0x87, 0xea);
 
 DEFINE_OLEGUID(IID_IUnknown,                  0x00000000, 0, 0);
 DEFINE_OLEGUID(IID_IDispatch,                 0x00020400, 0, 0);
@@ -135,6 +144,14 @@ add_oom_attachment (LPDISPATCH disp, wchar_t* inFile);
 char *
 get_pa_string (LPDISPATCH pDisp, const char *property);
 
+/* Queries the interface of the dispatcher for the id
+   id. Returns NULL on error. The returned Object
+   must be released.
+   Mainly useful to check if an object is what
+   it appears to be. */
+LPDISPATCH
+get_object_by_id (LPDISPATCH pDisp, REFIID id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/util.h b/src/util.h
index 09cde90..38924f8 100644
--- a/src/util.h
+++ b/src/util.h
@@ -80,6 +80,8 @@ const void *get_128bit_session_key (void);
 const void *get_64bit_session_marker (void);
 void *create_initialization_vector (size_t nbytes);
 
+#define debug_oom        (opt.enable_debug & DBG_OOM)
+#define debug_oom_extra  (opt.enable_debug & DBG_OOM_EXTRA)
 void log_debug (const char *fmt, ...) __attribute__ ((format (printf,1,2)));
 void log_error (const char *fmt, ...) __attribute__ ((format (printf,1,2)));
 void log_vdebug (const char *fmt, va_list a);
@@ -92,6 +94,9 @@ void log_hexdump (const void *buf, size_t buflen, const char *fmt,
 void log_window_hierarchy (HWND window, const char *fmt, 
                            ...) __attribute__ ((format (printf,2,3)));
 
+#define log_oom if (opt.enable_debug & DBG_OOM) log_debug
+#define log_oom_extra if (opt.enable_debug & DBG_OOM_EXTRA) log_debug
+
 const char *log_srcname (const char *s);
 #define SRCNAME log_srcname (__FILE__)
      

-----------------------------------------------------------------------


hooks/post-receive
-- 
GnuPG extension for MS Outlook
http://git.gnupg.org




More information about the Gnupg-commits mailing list