[git] GpgOL - branch, mime-addin, updated. gpgol-1.2.0-28-g312f71f

by Andre Heinecke cvs at cvs.gnupg.org
Mon Sep 21 15:19:31 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 updated
       via  312f71f0904b8642674ffd2b1af5d39f82a5f03d (commit)
       via  930a31db041544f0d171b1220f491e00fcc69b8d (commit)
       via  d706915a7b7c06e51122f0a732603b6d522477eb (commit)
       via  8b2a69864ba6ca7b192366c71c8f3c6df00b1f28 (commit)
      from  6286d7355fbb16060a5354fb5d3ccf1b624615cb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 312f71f0904b8642674ffd2b1af5d39f82a5f03d
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Sep 21 15:06:57 2015 +0200

    Add proper Attachment handling for MIME messages.
    
    Attachments are now session decrypted in the read event and
    session encrypted again in the write event.
    
    * src/attachment.cpp, src/attachment.h: Functions for attachment
    Session encryption / decryption.
    * src/Makefile.am: Add new files.
    * src/mailitem-events.cpp (~MailItemEvents): Resolve Macro
    to avoid confusing bracing.
    (MailItemEvents::handle_read): Remove session encryption from
    attachments.
    (MailItemEvents::invoke): Track "wipe" status. Session encrypt
    attachments in write event.
    * src/mapihelp.cpp (get_gpgolattachtype): Unstatic.
    * src/mapihelp.h (get_gpgolattachtype): Expose.
    (attachtype_t): Define attachment type for temporary unprotected
    Attachments.
    
    --
    
    The code will probably be changed to just untprotect an attachment
    when it is accessed in the BeforeAttachmentWriteToTempFile event.

diff --git a/src/Makefile.am b/src/Makefile.am
index c983dcc..71246a3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -71,7 +71,6 @@ gpgol_SOURCES = \
 	mapihelp.cpp mapihelp.h     \
 	mymapi.h  mymapitags.h      \
 	serpent.c serpent.h         \
-        vasprintf.c                 \
 	ext-commands.cpp ext-commands.h       \
 	user-events.cpp     user-events.h     \
 	session-events.cpp  session-events.h  \
@@ -90,7 +89,8 @@ gpgol_SOURCES = \
 	parsetlv.c parsetlv.h \
 	filetype.c filetype.h \
 	eventsinks.h application-events.cpp \
-	mailitem-events.cpp
+	mailitem-events.cpp \
+	attachment.h attachment.cpp
 
 
 #treeview_SOURCES = treeview.c
diff --git a/src/attachment.cpp b/src/attachment.cpp
new file mode 100644
index 0000000..9ecd970
--- /dev/null
+++ b/src/attachment.cpp
@@ -0,0 +1,324 @@
+/* attachment.cpp - Functions for attachment handling
+ *    Copyright (C) 2005, 2007 g10 Code GmbH
+ *    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/>.
+ */
+
+#include "config.h"
+#include "common.h"
+#include "attachment.h"
+#include "serpent.h"
+#include "oomhelp.h"
+#include "mymapitags.h"
+#include "mapihelp.h"
+
+#include <objidlbase.h>
+
+#define COPYBUFFERSIZE 4096
+
+#define IV_DEFAULT_LEN 16
+
+/** Decrypt the first 16 bytes of stream and check that it contains
+  our header. Return 0 on success. */
+static int
+check_header (LPSTREAM stream, symenc_t symenc)
+{
+  HRESULT hr;
+  char tmpbuf[16];
+  ULONG nread;
+  hr = stream->Read (tmpbuf, 16, &nread);
+  if (hr || nread != 16)
+    {
+      log_error ("%s:%s: Read failed: hr=%#lx", SRCNAME, __func__, hr);
+      return -1;
+    }
+  symenc_cfb_decrypt (symenc, tmpbuf, tmpbuf, 16);
+  if (memcmp (tmpbuf, "GpgOL attachment", 16))
+    {
+      log_error ("%s:%s: Invalid header.",
+                 SRCNAME, __func__);
+      char buf2 [17];
+      snprintf (buf2, 17, "%s", tmpbuf);
+      log_error("Buf2: %s", buf2);
+      return -1;
+    }
+  return 0;
+}
+
+/** Encrypts or decrypts a stream in place using the symenc context.
+  Returns 0 on success. */
+static int
+do_crypt_stream (LPSTREAM stream, symenc_t symenc, bool encrypt)
+{
+  char *buf = NULL;
+  HRESULT hr;
+  ULONG nread;
+  bool fixed_str_written = false;
+  int rc = -1;
+  ULONG written = 0;
+  /* The original intention was to use IStream::Clone to have
+     an independent read / write stream. But the MAPI attachment
+     stream returns E_NOT_IMPLMENTED for that :-)
+     So we manually track the read and writepos. Read is offset
+     at 16 because of the GpgOL message. */
+  LARGE_INTEGER readpos = {0},
+                writepos = {0};
+
+  if (!encrypt)
+    {
+      readpos.QuadPart = 16;
+    }
+
+  buf = (char*)xmalloc (COPYBUFFERSIZE);
+  do
+    {
+      hr = stream->Read (buf, COPYBUFFERSIZE, &nread);
+      if (hr)
+        {
+          log_error ("%s:%s: Read failed: hr=%#lx", SRCNAME, __func__, hr);
+          goto done;
+        }
+      if (!nread)
+        {
+          break;
+        }
+      readpos.QuadPart += nread;
+      stream->Seek(writepos, STREAM_SEEK_SET, NULL);
+      if (nread && encrypt && !fixed_str_written)
+        {
+          char tmpbuf[16];
+          /* Write an encrypted fixed 16 byte string which we need to
+             check at decryption time to see whether we have actually
+             encrypted it using this session key.  */
+          symenc_cfb_encrypt (symenc, tmpbuf, "GpgOL attachment", 16);
+          stream->Write (tmpbuf, 16, NULL);
+          fixed_str_written = true;
+          writepos.QuadPart = 16;
+        }
+      if (encrypt)
+        {
+          symenc_cfb_encrypt (symenc, buf, buf, nread);
+        }
+      else
+        {
+          symenc_cfb_decrypt (symenc, buf, buf, nread);
+        }
+
+        hr = stream->Write (buf, nread, &written);
+        if (FAILED (hr) || written != nread)
+          {
+            log_error ("%s:%s: Write failed: %i", SRCNAME, __func__, __LINE__);
+            goto done;
+          }
+        writepos.QuadPart += written;
+        stream->Seek(readpos, STREAM_SEEK_SET, NULL);
+      }
+    while (nread == COPYBUFFERSIZE);
+  rc = 0;
+
+done:
+  xfree (buf);
+
+  if (rc)
+    {
+      stream->Revert ();
+    }
+  else
+    {
+      stream->Commit (0);
+    }
+
+  return rc;
+}
+
+/** If encrypt is set to true this will encrypt the attachment
+  data with serpent otherwiese it will decrypt.
+  This function handles the mapi side of things.
+  */
+static int
+do_crypt_mapi (LPATTACH att, bool encrypt)
+{
+  char *iv;
+  ULONG tag;
+  size_t ivlen = IV_DEFAULT_LEN;
+  symenc_t symenc = NULL;
+  HRESULT hr;
+  LPSTREAM stream = NULL;
+  int rc = -1;
+
+  if (!att)
+    {
+      log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+      return -1;
+    }
+
+  /* Get or create a new IV */
+  if (get_gpgolprotectiv_tag ((LPMESSAGE)att, &tag) )
+    {
+      log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+      return -1;
+    }
+  if (encrypt)
+    {
+      iv = (char*)create_initialization_vector (IV_DEFAULT_LEN);
+    }
+  else
+    {
+      iv = mapi_get_binary_prop ((LPMESSAGE)att, tag, &ivlen);
+    }
+  if (!iv)
+    {
+      log_error ("%s:%s: Error creating / getting IV: %i", SRCNAME,
+                 __func__, __LINE__);
+      goto done;
+    }
+
+  symenc = symenc_open (get_128bit_session_key (), 16, iv, ivlen);
+  xfree (iv);
+  if (!symenc)
+    {
+      log_error ("%s:%s: can't open encryption context", SRCNAME, __func__);
+      goto done;
+    }
+
+  hr = att->OpenProperty (PR_ATTACH_DATA_BIN, &IID_IStream,
+                          0, MAPI_MODIFY, (LPUNKNOWN*) &stream);
+  if (FAILED (hr))
+    {
+      log_error ("%s:%s: can't open data stream of attachment: hr=%#lx",
+                 SRCNAME, __func__, hr);
+      goto done;
+    }
+
+  /* When decrypting check the first 16 bytes for the header */
+  if (!encrypt && check_header (stream, symenc))
+    {
+      goto done;
+    }
+
+  if (FAILED (hr))
+    {
+      log_error ("%s:%s: can't create temp file: hr=%#lx",
+                 SRCNAME, __func__, hr);
+      goto done;
+    }
+
+  if (do_crypt_stream (stream, symenc, encrypt))
+    {
+      log_error ("%s:%s: stream handling failed",
+                 SRCNAME, __func__);
+      goto done;
+    }
+  rc = 0;
+
+done:
+  if (symenc)
+    symenc_close (symenc);
+  RELDISP (stream);
+
+  return rc;
+}
+
+/** Protect or unprotect attachments.*/
+static int
+do_crypt (LPDISPATCH mailitem, bool protect)
+{
+  LPDISPATCH attachments = get_oom_object (mailitem, "Attachments");
+  LPMESSAGE message = get_oom_base_message (mailitem);
+  int count = 0;
+  int err = -1;
+  char *item_str;
+  int i;
+  ULONG tag_id;
+
+  if (!attachments || !message)
+    {
+      log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+      return -1;
+    }
+  count = get_oom_int (attachments, "Count");
+
+  if (get_gpgolattachtype_tag (message, &tag_id))
+    {
+      log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+      goto done;
+    }
+
+  if (count < 1)
+    {
+      log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+      goto done;
+    }
+
+  /* Yes the items start at 1! */
+  for (i = 1; i <= count; i++)
+    {
+      LPDISPATCH attachment;
+      LPATTACH mapi_attachment;
+      attachtype_t att_type;
+
+      if (asprintf (&item_str, "Item(%i)", i) == -1)
+        {
+          log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+          goto done;
+        }
+
+      attachment = get_oom_object (attachments, item_str);
+      xfree (item_str);
+      if (!attachment)
+        {
+          log_error ("%s:%s: Error: %i", SRCNAME, __func__, __LINE__);
+        }
+      mapi_attachment = (LPATTACH) get_oom_iunknown (attachment,
+                                                     "MapiObject");
+
+      att_type = get_gpgolattachtype (mapi_attachment, tag_id);
+      if ((protect && att_type == ATTACHTYPE_FROMMOSS_DEC) ||
+          (!protect && att_type == ATTACHTYPE_FROMMOSS))
+        {
+          if (do_crypt_mapi (mapi_attachment, protect))
+            {
+              log_error ("%s:%s: Error: Session crypto failed.",
+                         SRCNAME, __func__);
+              mapi_attachment->Release ();
+              attachment->Release ();
+              goto done;
+            }
+        }
+      mapi_attachment->Release ();
+      attachment->Release ();
+    }
+  err = 0;
+
+done:
+
+  RELDISP (message);
+  RELDISP (attachments);
+  return err;
+}
+
+int
+protect_attachments (LPDISPATCH mailitem)
+{
+  return do_crypt (mailitem, true);
+}
+
+int
+unprotect_attachments (LPDISPATCH mailitem)
+{
+  return do_crypt (mailitem, false);
+}
diff --git a/src/attachment.h b/src/attachment.h
new file mode 100644
index 0000000..932a21a
--- /dev/null
+++ b/src/attachment.h
@@ -0,0 +1,52 @@
+/* attachment.h - Functions for attachment handling
+ *    Copyright (C) 2005, 2007 g10 Code GmbH
+ *    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 ATTACHMENT_H
+#define ATTACHMENT_H
+
+#include <windows.h>
+
+/** Protect attachments so that it can be stored
+  by outlook. This means to symetrically encrypt the
+  data with the session key.
+
+  This will change the messagetype back to
+  ATTACHTYPE_FROMMOSS it is only supposed to be
+  called on attachments with the Attachmentype
+  ATTACHTYPE_FROMMOSS_DEC.
+
+  The dispatch paramenter should be a mailitem.
+
+  Returns 0 on success.
+*/
+int
+protect_attachments (LPDISPATCH mailitem);
+
+/** Remove the symetric session encryption of the attachments.
+
+  The dispatch paramenter should be a mailitem.
+
+  This will change the messsagetype to
+  ATTACHTYPE_FROMMOSS_DEC it should only be called
+  with attachments of the type ATTACHTYPE_FROMMOSS.
+
+  Returns 0 on success. */
+int
+unprotect_attachments (LPDISPATCH mailitem);
+#endif // ATTACHMENT_H
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index 98f6385..34ac116 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -24,6 +24,9 @@
 #include "message.h"
 #include "oomhelp.h"
 #include "ocidl.h"
+#include "attachment.h"
+#include "mapihelp.h"
+
 
 typedef enum
   {
@@ -63,6 +66,7 @@ private:
   bool m_send_seen,   /* The message is about to be submitted */
        m_want_html,    /* Encryption of HTML is desired. */
        m_processed,    /* The message has been porcessed by us.  */
+       m_needs_wipe,   /* We have added plaintext to the mesage. */
        m_was_encrypted; /* The original message was encrypted.  */
 
   HRESULT handle_before_read();
@@ -79,9 +83,15 @@ MailItemEvents::MailItemEvents() :
     m_want_html(false),
     m_processed(false)
 {
-/* The event sink default dtor closes this for us. */
-EVENT_SINK_DEFAULT_DTOR(MailItemEvents)
+}
 
+MailItemEvents::~MailItemEvents()
+{
+  if (m_pCP)
+    m_pCP->Unadvise(m_cookie);
+  if (m_object)
+    m_object->Release();
+}
 
 HRESULT
 MailItemEvents::handle_read()
@@ -113,6 +123,12 @@ MailItemEvents::handle_read()
 
   xfree (body);
 
+  if (unprotect_attachments (m_object))
+    {
+      log_error ("%s:%s: Failed to unprotect attachments. \n",
+                 SRCNAME, __func__);
+    }
+
   return S_OK;
 }
 
@@ -139,8 +155,10 @@ MailItemEvents::handle_before_read()
   log_debug ("%s:%s: incoming handler status: %i",
              SRCNAME, __func__, err);
   message->Release ();
+  return S_OK;
 }
 
+
 HRESULT
 MailItemEvents::handle_after_write()
 {
@@ -170,6 +188,14 @@ MailItemEvents::handle_after_write()
   return S_OK;
 }
 
+/* The main Invoke function. The return value of this
+   function does not appear to have any effect on outlook
+   although I have read in an example somewhere that you
+   should return S_OK so that outlook continues to handle
+   the event I have not yet seen any effect by returning
+   error values here and no MSDN documentation about the
+   return values.
+*/
 EVENT_SINK_INVOKE(MailItemEvents)
 {
   USE_INVOKE_ARGS
@@ -183,7 +209,8 @@ EVENT_SINK_INVOKE(MailItemEvents)
         {
           if (m_processed)
             {
-              return handle_read();
+              m_needs_wipe = m_was_encrypted;
+              handle_read();
             }
           return S_OK;
         }
@@ -202,16 +229,39 @@ EVENT_SINK_INVOKE(MailItemEvents)
         }
       case Write:
         {
-          if (m_wasencrypted && m_processed && !m_send_seen)
+          /* This is a bit strange. We sometimes get multiple write events
+             without a read in between. When we access the message in
+             the second event it fails and if we cancel the event outlook
+             crashes. So we have keep the m_needs_wipe state variable
+             to keep track of that. */
+          if (parms->cArgs != 1 || parms->rgvarg[0].vt != (VT_BOOL | VT_BYREF))
+           {
+             /* This happens in the weird case */
+             log_oom ("%s:%s: Uncancellable write event.",
+                      SRCNAME, __func__);
+             break;
+           }
+          if (m_processed && m_needs_wipe && !m_send_seen)
             {
-              log_debug ("%s:%s: Wiping plaintext from body of Message: %lx \n",
-                         SRCNAME, __func__, m_object, dispid);
-              put_oom_string (m_object, "HTMLBody", "");
-              put_oom_string (m_object, "Body", "");
+              log_debug ("%s:%s: Message %p removing plaintext from Message.",
+                         SRCNAME, __func__, m_object);
+              if (put_oom_string (m_object, "HTMLBody", "") ||
+                  put_oom_string (m_object, "Body", "") ||
+                  protect_attachments (m_object))
+                {
+                  /* An error cleaning the mail should not happen normally.
+                     But just in case there is an error we cancel the
+                     write here. */
+                  log_debug ("%s:%s: Failed to remove plaintext.",
+                             SRCNAME, __func__);
+                  *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE;
+                  return E_ABORT;
+                }
+              m_needs_wipe = false;
             }
         }
       default:
-        log_debug ("%s:%s: Message:%lx Unhandled Event: %lx \n",
+        log_oom_extra ("%s:%s: Message:%p Unhandled Event: %lx \n",
                        SRCNAME, __func__, m_object, dispid);
     }
   return S_OK;
diff --git a/src/mapihelp.cpp b/src/mapihelp.cpp
index 1d6d7c5..81b3fd2 100644
--- a/src/mapihelp.cpp
+++ b/src/mapihelp.cpp
@@ -1852,7 +1852,7 @@ get_attach_mime_tag (LPATTACH obj)
 
 /* Return the GpgOL Attach Type for attachment OBJ.  Tag needs to be
    the tag of that property. */
-static attachtype_t
+attachtype_t
 get_gpgolattachtype (LPATTACH obj, ULONG tag)
 {
   HRESULT hr;
diff --git a/src/mapihelp.h b/src/mapihelp.h
index 05417c6..8173b94 100644
--- a/src/mapihelp.h
+++ b/src/mapihelp.h
@@ -50,9 +50,13 @@ typedef enum
     ATTACHTYPE_FROMMOSS = 2,     /* Attachment created from MOSS.  */
     ATTACHTYPE_MOSSTEMPL = 3,    /* Attachment has been created in the
                                     course of sending a message */ 
-    ATTACHTYPE_PGPBODY = 4       /* Attachment contains the original
+    ATTACHTYPE_PGPBODY = 4,      /* Attachment contains the original
                                     PGP message body of PGP inline
                                     encrypted messages.  */
+    ATTACHTYPE_FROMMOSS_DEC = 5  /* A FROMMOSS attachment that has been
+                                    temporarily decrypted and needs to be
+                                    encrypted before it is written back
+                                    into storage. */
   }
 attachtype_t;
 
@@ -167,6 +171,7 @@ int   mapi_delete_gpgol_body_attachment (LPMESSAGE message);
 
 int   mapi_attachment_to_body (LPMESSAGE message, mapi_attach_item_t *item);
 
+attachtype_t get_gpgolattachtype (LPATTACH obj, ULONG tag);
 #ifdef __cplusplus
 }
 #endif

commit 930a31db041544f0d171b1220f491e00fcc69b8d
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Sep 21 15:01:50 2015 +0200

    Add helper method to invoke a function.
    
    * src/oomhelp.cpp, src/oomhelp.h (invoke_oom_method): Invoke
    a generic method without arguments with an optional return value.
    
    --
    I've used this during some experiments calling Delete() on
    attachments. Could be useful for other things.

diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
index 6648918..d3f284d 100644
--- a/src/oomhelp.cpp
+++ b/src/oomhelp.cpp
@@ -1068,3 +1068,28 @@ get_oom_base_message (LPDISPATCH mailitem)
   mapi_message->Release ();
   return ret;
 }
+
+int
+invoke_oom_method (LPDISPATCH pDisp, const char *name, VARIANT *rVariant)
+{
+  HRESULT hr;
+  DISPID dispid;
+
+  dispid = lookup_oom_dispid (pDisp, name);
+  if (dispid != DISPID_UNKNOWN)
+    {
+      DISPPARAMS dispparams = {NULL, NULL, 0, 0};
+
+      hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
+                          DISPATCH_METHOD, &dispparams,
+                          rVariant, NULL, NULL);
+      if (hr != S_OK)
+        {
+          log_debug ("%s:%s: Method '%s' invokation failed: %#lx",
+                     SRCNAME, __func__, name, hr);
+          return false;
+        }
+    }
+
+  return true;
+}
diff --git a/src/oomhelp.h b/src/oomhelp.h
index 7c2f967..66c9cab 100644
--- a/src/oomhelp.h
+++ b/src/oomhelp.h
@@ -171,6 +171,16 @@ get_oom_message (LPDISPATCH mailitem);
 LPMESSAGE
 get_oom_base_message (LPDISPATCH mailitem);
 
+/* Invoke a method of an outlook object.
+   returns true on success false otherwise.
+
+   rVariant should either point to a propery initialized
+   variant (initinalized wiht VariantInit) to hold
+   the return value or a pointer to NULL.
+   */
+int
+invoke_oom_method (LPDISPATCH pDisp, const char *name, VARIANT *rVariant);
+
 #ifdef __cplusplus
 }
 #endif

commit d706915a7b7c06e51122f0a732603b6d522477eb
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Sep 21 14:58:17 2015 +0200

    Show exception info in case put_oom_string fails.
    
    * src/oomhelp.cpp (put_oom_string): Show exception info.
    
    --
    Developing code inside events regularly leads to surprising
    "This can not be modified from within this context" errors.

diff --git a/src/oomhelp.cpp b/src/oomhelp.cpp
index 0b1f144..6648918 100644
--- a/src/oomhelp.cpp
+++ b/src/oomhelp.cpp
@@ -466,6 +466,7 @@ put_oom_string (LPDISPATCH pDisp, const char *name, const char *string)
   DISPPARAMS dispparams;
   VARIANT aVariant[1];
   BSTR bstring;
+  EXCEPINFO execpinfo;
 
   dispid = lookup_oom_dispid (pDisp, name);
   if (dispid == DISPID_UNKNOWN)
@@ -490,12 +491,13 @@ put_oom_string (LPDISPATCH pDisp, const char *name, const char *string)
   dispparams.cNamedArgs = 1;
   hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
                       DISPATCH_PROPERTYPUT, &dispparams,
-                      NULL, NULL, NULL);
+                      NULL, &execpinfo, NULL);
   SysFreeString (bstring);
   if (hr != S_OK)
     {
       log_debug ("%s:%s: Putting '%s' failed: %#lx", 
                  SRCNAME, __func__, name, hr);
+      dump_excepinfo (execpinfo);
       return -1;
     }
   return 0;

commit 8b2a69864ba6ca7b192366c71c8f3c6df00b1f28
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Sep 21 14:54:56 2015 +0200

    Log mailitem event handler installation
    
    * src/application-events.cpp (ApplicationEvents::Invoke): Log
     for which message a sink is installed.
    
    --
    We work under the assumption that there is only one event
    sink per messageitem. This debug output helps to confirm that
    in case we see weird event orders.

diff --git a/src/application-events.cpp b/src/application-events.cpp
index b2fbc3b..8b3b0c2 100644
--- a/src/application-events.cpp
+++ b/src/application-events.cpp
@@ -80,6 +80,8 @@ EVENT_SINK_INVOKE(ApplicationEvents)
                          SRCNAME, __func__);
               break;
             }
+          log_oom ("%s:%s: Installing event sink on mailitem: %p",
+                   SRCNAME, __func__, mailItem);
           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

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

Summary of changes:
 src/Makefile.am            |   4 +-
 src/application-events.cpp |   2 +
 src/attachment.cpp         | 324 +++++++++++++++++++++++++++++++++++++++++++++
 src/attachment.h           |  52 ++++++++
 src/mailitem-events.cpp    |  68 ++++++++--
 src/mapihelp.cpp           |   2 +-
 src/mapihelp.h             |   7 +-
 src/oomhelp.cpp            |  29 +++-
 src/oomhelp.h              |  10 ++
 9 files changed, 484 insertions(+), 14 deletions(-)
 create mode 100644 src/attachment.cpp
 create mode 100644 src/attachment.h


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




More information about the Gnupg-commits mailing list