[git] GpgOL - branch, nomapi, updated. gpgol-1.4.0-144-gb6b1b43

by Andre Heinecke cvs at cvs.gnupg.org
Mon Nov 7 15:46:00 CET 2016


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, nomapi has been updated
       via  b6b1b43ca1f29bf3afebd53d8afb0b3d7b3e7f4d (commit)
       via  2d411103d6ce9ff3b69353a095ac862c15312783 (commit)
       via  68835bfc6096603361038b985e9a93a9b42eb850 (commit)
       via  7c002f5b713786022964df6eae09f6dd06ddb0e0 (commit)
       via  c21454e49cff01b0200f02c58812a696f7127050 (commit)
       via  aadd8026eca38983fa14e1045400e8e9c0f50508 (commit)
       via  765e04b5e0fb6ce3ebcf2374a6e09dc8e3005ca9 (commit)
       via  b41e5bcfaeab4964c0609d755177f31ecb5e458c (commit)
       via  24e1932dc7c974ce18f8171a9e8c16bdc1a359a5 (commit)
      from  ada53e40e5c3907e8ae9539bd3212b57b48aba43 (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 b6b1b43ca1f29bf3afebd53d8afb0b3d7b3e7f4d
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Nov 7 15:28:53 2016 +0100

    Remove the need to revert mails
    
    * src/application-events.cpp (EVENT_SINK_INVOKE): Remove comment.
    * src/gpgoladdin.cpp (GpgolAddin::OnDisconnection): Close instead
    revert.
    (GpgolAddin::OnStartupComplete): Create Window message hook.
    * src/mail.cpp (Mail::close_all_mails): New.
    * src/mail.h: Update accordingly.
    * src/mailitem-events.cpp (request_close): New.
    src/mailitem-events.cpp (EVENT_SINK_INVOKE): Update event
    handling to new logic. See comments.
    * src/windowmessages.cpp (gpgol_hook): New.
    (create_message_hook): New. Registers gpgol_hook.
    src/windowmessages.h: Update accordingly.
    
    --
    This is basically the yewel of the nomapi branch. Without
    persistent changes in MAPI we can just close the Mails with
    discard changes set to true to "revert" our mails. This
    removes the need for a revert and Outlook won't create new
    mails containing our reverted mails.
    
    There should be no more need for revert at all. It's left
    in as an additional fallback in case something fails.

diff --git a/src/application-events.cpp b/src/application-events.cpp
index f70c44a..8f089d4 100644
--- a/src/application-events.cpp
+++ b/src/application-events.cpp
@@ -97,11 +97,7 @@ EVENT_SINK_INVOKE(ApplicationEvents)
       case Quit:
         {
           log_debug ("%s:%s: Quit event", SRCNAME, __func__);
-          /* Reverting all mails here can cause outlook to go
-             into an endless sync state after the next start.
-             So we can't do it. Needs handling.
-             Mail::revert_all_mails();
-             */
+          break;
         }
       default:
         log_oom_extra ("%s:%s: Unhandled Event: %lx \n",
diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp
index 7c0c4e9..9e80808 100644
--- a/src/gpgoladdin.cpp
+++ b/src/gpgoladdin.cpp
@@ -176,7 +176,8 @@ GpgolAddin::GpgolAddin (void) : m_lRef(0),
   m_addin(nullptr),
   m_applicationEventSink(nullptr),
   m_explorersEventSink(nullptr),
-  m_disabled(false)
+  m_disabled(false),
+  m_hook(nullptr)
 {
   read_options ();
   use_mime_ui = opt.mime_ui;
@@ -200,6 +201,8 @@ GpgolAddin::~GpgolAddin (void)
   engine_deinit ();
   write_options ();
 
+  UnhookWindowsHookEx (m_hook);
+
   addin_instance = NULL;
 
   log_debug ("%s:%s: Object deleted\n", SRCNAME, __func__);
@@ -299,7 +302,7 @@ GpgolAddin::OnDisconnection (ext_DisconnectMode RemoveMode,
      does not allow us any OOM calls then and only returns
      "Unexpected error" in that case. Weird. */
 
-  if (Mail::revert_all_mails ())
+  if (Mail::close_all_mails ())
     {
       MessageBox (NULL,
                   "Failed to remove plaintext from at least one message.\n\n"
@@ -429,6 +432,13 @@ GpgolAddin::OnStartupComplete (SAFEARRAY** custom)
                  SRCNAME, __func__);
       return E_NOINTERFACE;
     }
+
+  if (!(m_hook = create_message_hook ()))
+    {
+      log_error ("%s:%s: Failed to create messagehook. ",
+                 SRCNAME, __func__);
+    }
+
   /* Set up categories */
   const char *decCategory = _("GpgOL: Encrypted Message");
   const char *verifyCategory = _("GpgOL: Verified Sender");
diff --git a/src/gpgoladdin.h b/src/gpgoladdin.h
index a871348..316bbaf 100644
--- a/src/gpgoladdin.h
+++ b/src/gpgoladdin.h
@@ -213,7 +213,7 @@ private:
   LPDISPATCH m_explorersEventSink;
   LPDISPATCH m_ribbon_control;
   bool m_disabled;
-
+  HHOOK m_hook;
 };
 
 class GpgolAddinFactory: public IClassFactory
diff --git a/src/mail.cpp b/src/mail.cpp
index cb015fd..4f8fb7b 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -825,6 +825,30 @@ Mail::get_sender ()
 }
 
 int
+Mail::close_all_mails ()
+{
+  int err = 0;
+  std::map<LPDISPATCH, Mail *>::iterator it;
+  TRACEPOINT;
+  for (it = g_mail_map.begin(); it != g_mail_map.end(); ++it)
+    {
+      if (it->second->close ())
+        {
+          log_error ("Failed to close mail: %p ", it->first);
+          /* Should not happen */
+          if (it->second->revert())
+            {
+              err++;
+            }
+        }
+      else
+        {
+          delete it->second;
+        }
+    }
+  return err;
+}
+int
 Mail::revert_all_mails ()
 {
   int err = 0;
@@ -837,10 +861,11 @@ Mail::revert_all_mails ()
           err++;
           continue;
         }
+
       it->second->set_needs_save (true);
       if (!invoke_oom_method (it->first, "Save", NULL))
         {
-          log_error ("Failed to save reverted mail: %p ", it->first);
+          log_error ("Failed to save reverted mail: %p ", it->second);
           err++;
           continue;
         }
@@ -1029,7 +1054,7 @@ Mail::close ()
 
   /* Reset the uuid after discarding all changes in the oom
      so that we can still find ourself. */
-  set_uuid ();
+//  set_uuid ();
 
   /* Now that we have closed it with discard changes we no
      longer need to wipe the mail because the plaintext was
diff --git a/src/mail.h b/src/mail.h
index cef5819..21ca885 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -98,6 +98,21 @@ public:
     */
   static int revert_all_mails ();
 
+  /** @brief close all known Mail objects.
+    *
+    * Close our mail with discard changes set to true.
+    * This discards the plaintext / attachments. Afterwards
+    * it calls save if neccessary to sync back the collected
+    * property changes.
+    *
+    * This is the nicest of our three "Clean plaintext"
+    * functions. Will fallback to revert if closing fails.
+    * Closed mails are deleted.
+    *
+    * @returns the number of errors that occured.
+    */
+  static int close_all_mails ();
+
   /** @brief Reference to the mailitem. Do not Release! */
   LPDISPATCH item () { return m_mailitem; }
 
diff --git a/src/mailitem-events.cpp b/src/mailitem-events.cpp
index a3e569c..e1e5881 100644
--- a/src/mailitem-events.cpp
+++ b/src/mailitem-events.cpp
@@ -74,6 +74,8 @@ private:
   Mail * m_mail; /* The mail object related to this mailitem */
   bool m_send_seen;   /* The message is about to be submitted */
   bool m_decrypt_after_write;
+  bool m_ignore_unloads;
+  bool m_ignore_next_unload;
 };
 
 MailItemEvents::MailItemEvents() :
@@ -83,7 +85,9 @@ MailItemEvents::MailItemEvents() :
     m_ref(1),
     m_mail(NULL),
     m_send_seen (false),
-    m_decrypt_after_write(false)
+    m_decrypt_after_write(false),
+    m_ignore_unloads(false),
+    m_ignore_next_unload(false)
 {
 }
 
@@ -108,6 +112,19 @@ request_decrypt (LPVOID arg)
   return 0;
 }
 
+static DWORD WINAPI
+request_close (LPVOID arg)
+{
+  log_debug ("%s:%s: requesting close for: %s",
+             SRCNAME, __func__, (char*) arg);
+  if (do_in_ui_thread (REQUEST_CLOSE, arg))
+    {
+      log_debug ("%s:%s: close request failed for: %s",
+                 SRCNAME, __func__, (char*) arg);
+    }
+  return 0;
+}
+
 /* 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
@@ -133,6 +150,8 @@ EVENT_SINK_INVOKE(MailItemEvents)
     {
       case Open:
         {
+          log_oom_extra ("%s:%s: Open : %p",
+                         SRCNAME, __func__, m_mail);
           LPMESSAGE message;
           int draft_flags = 0;
           if (!opt.encrypt_default && !opt.sign_default)
@@ -156,9 +175,16 @@ EVENT_SINK_INVOKE(MailItemEvents)
             }
           set_gpgol_draft_info_flags (message, draft_flags);
           gpgol_release (message);
+
+          if (m_mail->is_crypto_mail())
+            {
+              m_ignore_unloads = true;
+            }
         }
       case BeforeRead:
         {
+          log_oom_extra ("%s:%s: BeforeRead : %p",
+                         SRCNAME, __func__, m_mail);
           if (m_mail->pre_process_message ())
             {
               log_error ("%s:%s: Pre process message failed.",
@@ -168,6 +194,21 @@ EVENT_SINK_INVOKE(MailItemEvents)
         }
       case Read:
         {
+          log_oom_extra ("%s:%s: Read : %p",
+                         SRCNAME, __func__, m_mail);
+          m_object->AddRef();
+          if (!m_mail->is_crypto_mail())
+            {
+              /* Not for us. */
+              break;
+            }
+          if (m_mail->set_uuid ())
+            {
+              log_debug ("%s:%s: Failed to set uuid.",
+                         SRCNAME, __func__);
+              delete m_mail; /* deletes this, too */
+              return S_OK;
+            }
           if (m_mail->decrypt_verify ())
             {
               log_error ("%s:%s: Decrypt message failed.",
@@ -231,6 +272,8 @@ EVENT_SINK_INVOKE(MailItemEvents)
              If this encryption is successful and we pass the send
              as then the encrypted data is sent.
            */
+          log_oom_extra ("%s:%s: Send : %p",
+                         SRCNAME, __func__, m_mail);
           if (parms->cArgs != 1 || parms->rgvarg[0].vt != (VT_BOOL | VT_BYREF))
            {
              log_debug ("%s:%s: Uncancellable send event.",
@@ -257,6 +300,8 @@ EVENT_SINK_INVOKE(MailItemEvents)
         }
       case Write:
         {
+          log_oom_extra ("%s:%s: Write : %p",
+                         SRCNAME, __func__, m_mail);
           /* 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
@@ -279,25 +324,19 @@ EVENT_SINK_INVOKE(MailItemEvents)
                  to enable reverting this mails.
                  */
               *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE;
-              log_oom ("%s:%s: Canceling write event.",
+              log_debug ("%s:%s: Canceling write event.",
                          SRCNAME, __func__);
               return S_OK;
             }
-
-          if (m_mail->revert ())
-            {
-              /* 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;
-            }
+          log_debug ("%s:%s: Passing write event.",
+                     SRCNAME, __func__);
           m_mail->set_needs_save (false);
           break;
         }
       case AfterWrite:
         {
+          log_oom_extra ("%s:%s: AfterWrite : %p",
+                         SRCNAME, __func__, m_mail);
           if (m_send_seen)
             {
               m_send_seen = false;
@@ -310,23 +349,28 @@ EVENT_SINK_INVOKE(MailItemEvents)
               HANDLE thread = CreateThread (NULL, 0, request_decrypt,
                                             (LPVOID) uuid, 0, NULL);
               CloseHandle (thread);
+              m_decrypt_after_write = false;
             }
           break;
         }
       case Close:
         {
+          log_oom_extra ("%s:%s: Close : %p",
+                         SRCNAME, __func__, m_mail);
           if (m_mail->is_crypto_mail ())
             {
               /* Close. This happens when an Opened mail is closed.
                  To prevent the question of wether or not to save the changes
                  (Which would save the decrypted data without an event to
-                 prevent it) we save proactively. This happens by set_needs_save
-                 and calling save. Which will revert a mail because we never want
-                 to save unreverted mails.
+                 prevent it) we cancel the close and then either close it
+                 with discard changes or revert / save it.
+                 This happens with a window message as we can't invoke close from
+                 close.
 
                  But as a side effect the mail, if opened in the explorer still will
-                 be reverted, too. So shown as empty. This is bad. To prevent that
-                 we request a decrypt in the AfterWrite event.
+                 be reverted, too. So shown as empty. To prevent that
+                 we request a decrypt in the AfterWrite event which checks if the
+                 message is opened in the explorer. If not it destroys the mail.
 
                  Evil Hack: Outlook sends an Unload event after the message is closed
                  This is not true our Internal Object is kept alive if it is opened
@@ -334,26 +378,71 @@ EVENT_SINK_INVOKE(MailItemEvents)
                  the window message handler that checks for decrypt again if the
                  mail is currently open in the active explorer. If not we delete our
                  Mail object so that the message is released.
-              */
-              m_mail->set_needs_save (true);
+                 */
+              if (parms->cArgs != 1 || parms->rgvarg[0].vt != (VT_BOOL | VT_BYREF))
+                {
+                  /* This happens in the weird case */
+                  log_debug ("%s:%s: Uncancellable close event.",
+                             SRCNAME, __func__);
+                  break;
+                }
+              *(parms->rgvarg[0].pboolVal) = VARIANT_TRUE;
+              log_oom ("%s:%s: Canceling close event.",
+                       SRCNAME, __func__);
               m_decrypt_after_write = true;
-              invoke_oom_method (m_object, "Save", NULL);
+              m_ignore_unloads = false;
+              m_ignore_next_unload = true;
+
+              char *uuid = strdup (m_mail->get_uuid ().c_str());
+              HANDLE thread = CreateThread (NULL, 0, request_close,
+                                            (LPVOID) uuid, 0, NULL);
+              CloseHandle (thread);
             }
         }
       case Unload:
         {
-          if (!m_decrypt_after_write)
+          log_oom_extra ("%s:%s: Unload : %p",
+                         SRCNAME, __func__, m_mail);
+          /* Unload. Experiments have shown that this does not
+             mean a mail is actually unloaded in Outlook. E.g.
+             If it was open in an inspector and then closed we
+             see an unload event but the mail is still shown in
+             the explorer. Fun. On the other hand if a message
+             was opened and the explorer selection changes
+             we also get an unload but the mail is still open.
+
+             Really we still get events after the unload and
+             can make changes to the object.
+
+             In case the mail was opened m_ignore_unloads is set
+             to true so the mail is not removed when the message
+             selection changes. As close invokes decrypt_again
+             the mail object is removed there when the explorer
+             selection changed.
+
+             In case the mail was closed m_ignore_next_unload
+             is set so only the Unload thad follows the canceled
+             close is ignored and not the unload that comes from
+             our then triggered close (save / discard).
+
+
+             This is horribly hackish and feels wrong. But it
+             works.
+             */
+          if (m_ignore_unloads || m_ignore_next_unload)
             {
-              log_debug ("%s:%s: Removing Mail for message: %p.",
+              if (m_ignore_next_unload)
+                {
+                  m_ignore_next_unload = false;
+                }
+              log_debug ("%s:%s: Ignoring unload for message: %p.",
                          SRCNAME, __func__, m_object);
-              delete m_mail;
             }
           else
             {
-              /* See explanation in Close why this is not broken. */
-              log_debug ("%s:%s: Ignoring unload for message: %p.",
+              log_debug ("%s:%s: Removing Mail for message: %p.",
                          SRCNAME, __func__, m_object);
-              m_decrypt_after_write = false;
+              delete m_mail;
             }
           return S_OK;
         }
diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp
index fd3ee2e..585d0d0 100644
--- a/src/windowmessages.cpp
+++ b/src/windowmessages.cpp
@@ -181,3 +181,34 @@ do_in_ui_thread (gpgol_wmsg_type type, void *data)
     }
   return ctx.err;
 }
+
+
+LRESULT CALLBACK
+gpgol_hook(int code, WPARAM wParam, LPARAM lParam)
+{
+/* Once we are in the close events we don't have enough
+   control to revert all our changes so we have to do it
+   with this nice little hack by catching the WM_CLOSE message
+   before it reaches outlook. */
+  LPCWPSTRUCT cwp = (LPCWPSTRUCT) lParam;
+
+  if (cwp->message == WM_CLOSE)
+    {
+      log_debug ("%s:%s: WM_CLOSE windowmessage. Closing all mails.",
+                 SRCNAME, __func__);
+      Mail::revert_all_mails();
+    }
+  return CallNextHookEx (NULL, code, wParam, lParam);
+}
+
+/* Create the message hook for outlook's windowmessages
+   we are especially interested in WM_QUIT to do cleanups
+   and prevent the "Item has changed" question. */
+HHOOK
+create_message_hook()
+{
+  return SetWindowsHookEx (WH_CALLWNDPROC,
+                           gpgol_hook,
+                           NULL,
+                           GetCurrentThreadId());
+}
diff --git a/src/windowmessages.h b/src/windowmessages.h
index 36a621c..c7f275e 100644
--- a/src/windowmessages.h
+++ b/src/windowmessages.h
@@ -66,4 +66,9 @@ send_msg_to_ui_thread (wm_ctx_t *ctx);
   in the ui thread.  Returns the result. */
 int
 do_in_ui_thread (gpgol_wmsg_type type, void *data);
+
+/** Create our filter before outlook Window Messages. */
+HHOOK
+create_message_hook();
+
 #endif // WINDOWMESSAGES_H

commit 2d411103d6ce9ff3b69353a095ac862c15312783
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Nov 7 15:27:14 2016 +0100

    Disable ui invalidation in explorers for now
    
    * src/explorer-events.cpp, src/explorers-events.cpp
    (EVENT_SINK_INVOKE): Disable ui invalidation.
    
    --
    This triggers a bug causing duplicated mailitems so
    disabled for now.

diff --git a/src/explorer-events.cpp b/src/explorer-events.cpp
index f48f6ac..6336561 100644
--- a/src/explorer-events.cpp
+++ b/src/explorer-events.cpp
@@ -69,7 +69,7 @@ EVENT_SINK_INVOKE(ExplorerEvents)
         {
           log_oom_extra ("%s:%s: Selection change in explorer: %p",
                          SRCNAME, __func__, this);
-          gpgoladdin_invalidate_ui ();
+        //  gpgoladdin_invalidate_ui ();
           break;
         }
       case Close:
diff --git a/src/explorers-events.cpp b/src/explorers-events.cpp
index 476e11e..663a5a9 100644
--- a/src/explorers-events.cpp
+++ b/src/explorers-events.cpp
@@ -66,7 +66,6 @@ EVENT_SINK_INVOKE(ExplorersEvents)
               break;
 
             }
-          gpgoladdin_invalidate_ui ();
         }
       default:
         break;

commit 68835bfc6096603361038b985e9a93a9b42eb850
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Nov 7 14:50:10 2016 +0100

    Always discard changes on close for now
    
    * src/mail.cpp, src/mail.h (Mail::close): Remove save changes
    parameter.
    
    --
    We need to figure out if we want to save after disarding changes
    by ourself depending on property changes.

diff --git a/src/mail.cpp b/src/mail.cpp
index c7747e2..cb015fd 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -1013,14 +1013,14 @@ Mail::close_inspector ()
 }
 
 int
-Mail::close (bool discard)
+Mail::close ()
 {
   VARIANT aVariant[1];
   DISPPARAMS dispparams;
 
   dispparams.rgvarg = aVariant;
   dispparams.rgvarg[0].vt = VT_INT;
-  dispparams.rgvarg[0].intVal = discard ? 1 : 0;
+  dispparams.rgvarg[0].intVal = 1;
   dispparams.cArgs = 1;
   dispparams.cNamedArgs = 0;
 
diff --git a/src/mail.h b/src/mail.h
index 95f07c8..cef5819 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -254,9 +254,10 @@ public:
       by the caller. */
   char ** get_recipients () const;
 
-  /** Call close with discard changes true or false
-      returns the value of the oom call. */
-  int close (bool discard);
+  /** Call close with discard changes to discard
+      plaintext. returns the value of the oom close
+      call. */
+  int close ();
 
 private:
   void update_categories ();

commit 7c002f5b713786022964df6eae09f6dd06ddb0e0
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Nov 7 14:47:38 2016 +0100

    Add request_close windowmessage
    
    * src/windowmessage.h (REQUEST_CLOSE): Declare.
    * src/windowmessages.cpp (gpgol_window_proc): Handle REQUEST_CLOSE.
    * src/ribbon-callbacks.cpp (get_mail_from_control): Update to new
    get_unique_id signature.

diff --git a/src/ribbon-callbacks.cpp b/src/ribbon-callbacks.cpp
index 2bb80e5..977145a 100644
--- a/src/ribbon-callbacks.cpp
+++ b/src/ribbon-callbacks.cpp
@@ -1463,14 +1463,20 @@ get_mail_from_control (LPDISPATCH ctrl)
     }
   xfree (ctx_name);
 
+  char *uid;
   /* Get the uid of this item. */
-  char *uid = get_unique_id (mailitem, 0);
+  uid = get_unique_id (mailitem, 0, nullptr);
   if (!uid)
     {
-      log_oom ("%s:%s: Failed to get uid for %p .",
-               SRCNAME, __func__, mailitem);
-      gpgol_release (mailitem);
-      return NULL;
+      uid = mapi_get_uid (mailitem);
+      if (!uid)
+        {
+          log_oom ("%s:%s: Failed to get uid for %p .",
+                   SRCNAME, __func__, mailitem);
+          log_debug ("subject: %s", get_oom_string(mailitem, "Subject"));
+          gpgol_release (mailitem);
+          return NULL;
+        }
     }
 
   auto ret = Mail::get_mail_for_uuid (uid);
diff --git a/src/windowmessages.cpp b/src/windowmessages.cpp
index 2c6e7ea..fd3ee2e 100644
--- a/src/windowmessages.cpp
+++ b/src/windowmessages.cpp
@@ -77,7 +77,7 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
                   break;
                 }
 
-              char *active_uuid = get_unique_id (mailitem, 0);
+              char *active_uuid = get_unique_id (mailitem, 0, nullptr);
               if (!active_uuid || strcmp (active_uuid, uuid))
                 {
                   log_debug ("%s:%s: UUID mismatch",
@@ -86,20 +86,38 @@ gpgol_window_proc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
                   delete mail;
                   break;
                 }
+              log_debug ("%s:%s: Decrypting %s again",
+                         SRCNAME, __func__, uuid);
               xfree (uuid);
               xfree (active_uuid);
 
               mail->decrypt_verify ();
               break;
             }
-
-          break;
+          case (REQUEST_CLOSE):
+            {
+              char *uuid = (char *) ctx->data;
+              auto mail = Mail::get_mail_for_uuid (uuid);
+              if (!mail)
+                {
+                  log_debug ("%s:%s: Close request for uuid which is gone.",
+                             SRCNAME, __func__);
+                  break;
+                }
+              if (mail->close())
+                {
+                  log_debug ("%s:%s: Close request failed.",
+                             SRCNAME, __func__);
+                }
+              ctx->wmsg_type = REQUEST_DECRYPT;
+              gpgol_window_proc (hWnd, message, wParam, (LPARAM) ctx);
+              break;
+            }
           default:
             log_debug ("Unknown msg");
         }
         return DefWindowProc(hWnd, message, wParam, lParam);
     }
-
   return DefWindowProc(hWnd, message, wParam, lParam);
 }
 
diff --git a/src/windowmessages.h b/src/windowmessages.h
index d9580e2..36a621c 100644
--- a/src/windowmessages.h
+++ b/src/windowmessages.h
@@ -40,7 +40,9 @@ typedef enum _gpgol_wmsg_type
   UNKNOWN = 0,
   PARSING_DONE = 2, /* A mail was parsed. Data should be a pointer
                       to the mail object. */
-  REQUEST_DECRYPT = 3
+  REQUEST_DECRYPT = 3,
+  REQUEST_CLOSE = 4 /* Request the mail to be closed with discard
+                       changes set to true */
 } gpgol_wmsg_type;
 
 typedef struct

commit c21454e49cff01b0200f02c58812a696f7127050
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Nov 7 12:59:50 2016 +0100

    Use msgclass to determine if a mail is crypto
    
    * src/mail.cpp (is_crypto_mail): Use messageclass instead
    of processed.
    * src/mail.h: Update accordingly.
    
    --
    This makes the function usable after prerproceessing and
    not only after decryption.

diff --git a/src/mail.cpp b/src/mail.cpp
index 0168497..c7747e2 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -479,13 +479,23 @@ do_parsing (LPVOID arg)
   return 0;
 }
 
-int
-Mail::decrypt_verify()
+bool
+Mail::is_crypto_mail() const
 {
   if (m_type == MSGTYPE_UNKNOWN || m_type == MSGTYPE_GPGOL ||
       m_type == MSGTYPE_SMIME)
     {
       /* Not a message for us. */
+      return false;
+    }
+  return true;
+}
+
+int
+Mail::decrypt_verify()
+{
+  if (!is_crypto_mail())
+    {
       return 0;
     }
   if (m_needs_wipe)
diff --git a/src/mail.h b/src/mail.h
index 81ddf58..95f07c8 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -172,7 +172,7 @@ public:
   * @returns true if the mail was either signed or encrypted and we processed
   * it.
   */
-  bool is_crypto_mail () { return m_processed; }
+  bool is_crypto_mail () const;
 
   /** @brief This mail needs to be actually written.
   *

commit aadd8026eca38983fa14e1045400e8e9c0f50508
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Nov 7 12:57:05 2016 +0100

    Add IID and install functions for explorer sinks
    
    * src/eventsinks.h (install_ExplorerEvents_sink)
    (install_ExplorersEvents_sink): Declare.
    * src/oomhelp.h: Add missing uuids.

diff --git a/src/eventsinks.h b/src/eventsinks.h
index 0bcfc03..82f618d 100644
--- a/src/eventsinks.h
+++ b/src/eventsinks.h
@@ -25,4 +25,8 @@ LPDISPATCH install_ApplicationEvents_sink (LPDISPATCH obj);
 void detach_ApplicationEvents_sink (LPDISPATCH obj);
 LPDISPATCH install_MailItemEvents_sink (LPDISPATCH obj);
 void detach_MailItemEvents_sink (LPDISPATCH obj);
+LPDISPATCH install_ExplorerEvents_sink (LPDISPATCH obj);
+void detach_ExplorerEvents_sink (LPDISPATCH obj);
+LPDISPATCH install_ExplorersEvents_sink (LPDISPATCH obj);
+void detach_ExplorersEvents_sink (LPDISPATCH obj);
 #endif // EVENTSINKS_H
diff --git a/src/oomhelp.h b/src/oomhelp.h
index 74e7faf..35991ce 100644
--- a/src/oomhelp.h
+++ b/src/oomhelp.h
@@ -64,6 +64,10 @@ DEFINE_GUID(IID_IPictureDisp,
             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_ExplorerEvents, 0x0006300F, 0x0000, 0x0000,
+            0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
+DEFINE_GUID(IID_ExplorersEvents, 0x00063078, 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,

commit 765e04b5e0fb6ce3ebcf2374a6e09dc8e3005ca9
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Nov 7 12:53:07 2016 +0100

    Use shared_ptr for parser object
    
    * src/mail.cpp (m_parser): Change to shared_ptr
    (Mail::parsing_done): Check if parser already deleted.
    * src/mail.h: Update accordingly.
    
    --
    The state in which this happens should no longer be
    reached due to the previous commit that prevents
    duplication in the uuid map. Still better handle
    it.

diff --git a/src/mail.cpp b/src/mail.cpp
index d63b7cd..0168497 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -537,7 +537,7 @@ Mail::decrypt_verify()
       return 1;
     }
 
-  m_parser = new ParseController (cipherstream, m_type);
+  m_parser = std::shared_ptr <ParseController> (new ParseController (cipherstream, m_type));
   gpgol_release (cipherstream);
 
   HANDLE parser_thread = CreateThread (NULL, 0, do_parsing, (LPVOID) this, 0,
@@ -610,6 +610,31 @@ void
 Mail::parsing_done()
 {
   TRACEPOINT;
+  log_oom_extra ("Mail %p Parsing done for parser: %p",
+                 this, m_parser.get());
+  if (!m_parser)
+    {
+      /* This should not happen but it happens when outlook
+         sends multiple ItemLoad events for the same Mail
+         Object. In that case it could happen that one
+         parser was already done while a second is now
+         returning for the wrong mail (as it's looked up
+         by uuid.)
+
+         We have a check in get_uuid that the uuid was
+         not in the map before (and the parser is replaced).
+         So this really really should not happen. We
+         handle it anyway as we crash otherwise.
+
+         It should not happen because the parser is only
+         created in decrypt_verify which is called in the
+         read event. And even in there we check if the parser
+         was set.
+         */
+      log_error ("%s:%s: No parser obj. For mail: %p",
+                 SRCNAME, __func__, this);
+      return;
+    }
   /* Store the results. */
   m_decrypt_result = m_parser->decrypt_result ();
   m_verify_result = m_parser->verify_result ();
@@ -635,7 +660,6 @@ Mail::parsing_done()
     }
 
   /* Invalidate UI to set the correct sig status. */
-  delete m_parser;
   m_parser = nullptr;
   gpgoladdin_invalidate_ui ();
   TRACEPOINT;
diff --git a/src/mail.h b/src/mail.h
index 0385fbd..81ddf58 100644
--- a/src/mail.h
+++ b/src/mail.h
@@ -198,7 +198,7 @@ public:
 
   /** @brief get the associated parser.
     only valid while the actual parsing happens. */
-  ParseController *parser () { return m_parser; }
+  std::shared_ptr<ParseController> parser () { return m_parser; }
 
   /** To be called from outside once the paser was done.
    In Qt this would be a slot that is called once it is finished
@@ -276,7 +276,7 @@ private:
   int m_moss_position; /* The number of the original message attachment. */
   char *m_sender;
   msgtype_t m_type; /* Our messagetype as set in mapi */
-  ParseController *m_parser;
+  std::shared_ptr <ParseController> m_parser;
   GpgME::VerificationResult m_verify_result;
   GpgME::DecryptionResult m_decrypt_result;
   GpgME::Signature m_sig;

commit b41e5bcfaeab4964c0609d755177f31ecb5e458c
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Nov 7 12:50:13 2016 +0100

    Check for duplicates in mail map
    
    * src/mail.cpp (Mail::set_uuid): Check for duplicates in mail
    map and handle them.
    
    --
    Sometimes we have the troubling state that multiple
    item load events occur for the same mail,
    as identified by uuid. This is bad but now at least
    we have some handling and report it as an error
    otherwise it could lead to cases where a parser
    returned for a wrong mail
    
    According to documentation this should not
    happen as this means that multiple ItemLoad
    events occured for the same mailobject without
    unload / destruction of the mail.
    
    But it happens. If you invalidate the UI
    in the selection change event Outlook loads a
    new mailobject for the mail. Might happen in
    other surprising cases. We replace in that
    case as experiments have shown that the last
    mailobject is the one that is visible.

diff --git a/src/mail.cpp b/src/mail.cpp
index 3e2aa88..d63b7cd 100644
--- a/src/mail.cpp
+++ b/src/mail.cpp
@@ -1212,6 +1212,28 @@ Mail::set_uuid()
   if (m_uuid.empty())
     {
       m_uuid = uuid;
+      Mail *other = get_mail_for_uuid (uuid);
+      if (other)
+        {
+          /* According to documentation this should not
+             happen as this means that multiple ItemLoad
+             events occured for the same mailobject without
+             unload / destruction of the mail.
+
+             But it happens. If you invalidate the UI
+             in the selection change event Outlook loads a
+             new mailobject for the mail. Might happen in
+             other surprising cases. We replace in that
+             case as experiments have shown that the last
+             mailobject is the one that is visible.
+
+             Still troubling state so we log this as an error.
+             */
+          log_error ("%s:%s: There is another mail for %p "
+                     "with uuid: %s replacing it.",
+                     SRCNAME, __func__, m_mailitem, uuid);
+          delete other;
+        }
       g_uid_map.insert (std::pair<std::string, Mail *> (m_uuid, this));
       log_debug ("%s:%s: uuid for %p is now %s",
                  SRCNAME, __func__, this,

commit 24e1932dc7c974ce18f8171a9e8c16bdc1a359a5
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Mon Nov 7 12:40:43 2016 +0100

    Fix build by adding new event handlers to Makefile
    
    * src/Makefile.am (gpgol_SOURCES): Add new files.
    
    --
    Forgotten in previous commit.

diff --git a/src/Makefile.am b/src/Makefile.am
index ae4ad97..55a9a7e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -82,7 +82,8 @@ gpgol_SOURCES = \
 	exechelp.c exechelp.h \
 	addin-options.cpp addin-options.h \
 	parsecontroller.cpp parsecontroller.h \
-	mimedataprovider.cpp mimedataprovider.h
+	mimedataprovider.cpp mimedataprovider.h \
+	explorer-events.cpp explorers-events.cpp
 
 
 #treeview_SOURCES = treeview.c

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

Summary of changes:
 src/Makefile.am            |   3 +-
 src/application-events.cpp |   6 +-
 src/eventsinks.h           |   4 ++
 src/explorer-events.cpp    |   2 +-
 src/explorers-events.cpp   |   1 -
 src/gpgoladdin.cpp         |  14 ++++-
 src/gpgoladdin.h           |   2 +-
 src/mail.cpp               |  97 ++++++++++++++++++++++++++++---
 src/mail.h                 |  28 +++++++--
 src/mailitem-events.cpp    | 141 ++++++++++++++++++++++++++++++++++++---------
 src/oomhelp.h              |   4 ++
 src/ribbon-callbacks.cpp   |  16 +++--
 src/windowmessages.cpp     |  57 ++++++++++++++++--
 src/windowmessages.h       |   9 ++-
 14 files changed, 323 insertions(+), 61 deletions(-)


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




More information about the Gnupg-commits mailing list