Saved current experiments
authorWerner Koch <wk@gnupg.org>
Fri, 20 Nov 2009 12:10:25 +0000 (12:10 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 20 Nov 2009 12:10:25 +0000 (12:10 +0000)
doc/gpgol.texi
src/inspectors.cpp
src/mailitem.cpp
src/mailitem.h
src/message-events.cpp

index ba061e3..6c4ef57 100644 (file)
@@ -309,6 +309,8 @@ Tell about command events.
 Tell what the MIME parser is doing
 @item 256 (0x0100) (mime-data)
 Print data lines while parsing MIME.
+@item 512 (0x0200) (oom)
+Verbose object allocation reporting.
 @end table
 You may use the regular C-syntax for entering the value.  As an
 alternative you may use the names of the flags, separated by space or
index a32373b..40a2b28 100644 (file)
@@ -424,7 +424,7 @@ STDMETHODIMP_(void)
 GpgolInspectorEvents::Activate (void)
 {
   LPOOMINSPECTOR inspector;
-  // LPDISPATCH obj, obj2;
+  LPDISPATCH obj, obj2;
 
   log_debug ("%s:%s: Called (this=%p)", SRCNAME, __func__, this);
   
@@ -448,14 +448,14 @@ GpgolInspectorEvents::Activate (void)
     {
       m_first_activate_seen = true;
       add_inspector_controls (inspector);
-      // obj = get_oom_object (inspector, "get_CurrentItem");
-      // if (obj)
-      //   {
-      //     obj2 = install_GpgolItemEvents_sink (obj);
-      //     if (obj2)
-      //       obj2->Release ();
-      //     obj->Release ();
-      //   }
+      obj = get_oom_object (inspector, "get_CurrentItem");
+      if (obj)
+        {
+          obj2 = install_GpgolItemEvents_sink (obj);
+          if (obj2)
+            obj2->Release ();
+          obj->Release ();
+        }
     }
   
   update_crypto_info (inspector);
index dfa5886..9cdc2a5 100644 (file)
 #include "oomhelp.h"
 #include "eventsink.h"
 #include "mailitem.h"
-
+#include "mymapi.h"
+#include "mymapitags.h"
+#include "myexchext.h"
+#include "mapihelp.h"
+#include "message.h"
 
 /* Subclass of ItemEvents so that we can hook into the events.  */
 BEGIN_EVENT_SINK(GpgolItemEvents, IOOMItemEvents)
@@ -36,7 +40,12 @@ BEGIN_EVENT_SINK(GpgolItemEvents, IOOMItemEvents)
   STDMETHOD(Write)(THIS_ PBOOL cancel);
   STDMETHOD(Open)(THIS_ PBOOL cancel);
   STDMETHOD(Close)(THIS_ PBOOL cancel);
-EVENT_SINK_DEFAULT_CTOR(GpgolItemEvents)
+  STDMETHOD(Send)(THIS_ PBOOL cancel);
+  bool m_send_seen;
+EVENT_SINK_CTOR(GpgolItemEvents)
+{
+  m_send_seen = false;
+}
 EVENT_SINK_DEFAULT_DTOR(GpgolItemEvents)
 EVENT_SINK_INVOKE(GpgolItemEvents)
 {
@@ -57,7 +66,10 @@ EVENT_SINK_INVOKE(GpgolItemEvents)
         }
       break;
 
+    case 0xf002:
+    case 0xf003:
     case 0xf004:
+    case 0xf005:
       if (!(flags & DISPATCH_METHOD))
         goto badflags;
       if (!parms) 
@@ -74,6 +86,7 @@ EVENT_SINK_INVOKE(GpgolItemEvents)
             case 0xf002: Write (&cancel_default); break;
             case 0xf003: Open (&cancel_default); break;
             case 0xf004: Close (&cancel_default); break;
+            case 0xf005: Send (&cancel_default); break;
             }
           *parms->rgvarg[0].pboolVal = (cancel_default 
                                         ? VARIANT_TRUE:VARIANT_FALSE);
@@ -94,18 +107,112 @@ END_EVENT_SINK(GpgolItemEvents, IID_IOOMItemEvents)
 STDMETHODIMP
 GpgolItemEvents::Read (void)
 {
-  log_debug ("%s:%s: Called", SRCNAME, __func__);
+  log_debug ("%s:%s: Called (this=%p)", SRCNAME, __func__, this);
 
   return S_OK;
 }
 
 
-/* This is the event sink for a write event.  */
+/* This is the event sink for a write event.  OL2003 calls this method
+   before an ECE OnWrite.  */
 STDMETHODIMP
 GpgolItemEvents::Write (PBOOL cancel_default)
 {
-  (void)cancel_default;
-  log_debug ("%s:%s: Called", SRCNAME, __func__);
+  bool sign, encrypt, need_crypto, want_html;
+  HWND hwnd = NULL;  /* Fixme.  */
+  log_debug ("%s:%s: Called (this=%p) (send_seen=%d)",
+             SRCNAME, __func__, this, m_send_seen);
+
+  if (!m_send_seen)
+    return S_OK; /* The user is only saving the message.  */
+  m_send_seen = 0;
+
+  if (opt.disable_gpgol)
+    return S_OK; /* GpgOL is not active.  */
+  
+  // need_crypto = (!get_crypto_flags (eecb, &sign, &encrypt)
+  //                && (sign || encrypt));
+  need_crypto = true;
+  sign = true;
+  encrypt = false;
+
+    
+  /* If we are going to encrypt, check that the BodyFormat is
+     something we support.  This helps avoiding surprise by sending
+     out unencrypted messages. */
+  if (need_crypto)
+    {
+      HRESULT hr;
+      int rc;
+      LPUNKNOWN unknown;
+      LPMESSAGE message = NULL;
+      int bodyfmt;
+      protocol_t proto = PROTOCOL_UNKNOWN; /* Let the UI server select
+                                              the protocol.  */
+
+      bodyfmt = get_oom_int (m_object, "BodyFormat");
+
+      if (bodyfmt == 1)
+        want_html = 0;
+      else if (bodyfmt == 2)
+        want_html = 1;
+      else
+        {
+          log_debug ("%s:%s: BodyFormat is %d", SRCNAME, __func__, bodyfmt);
+          MessageBox (hwnd,
+                      _("Sorry, we can only encrypt plain text messages and\n"
+                      "no RTF messages. Please make sure that only the text\n"
+                      "format has been selected."),
+                      "GpgOL", MB_ICONERROR|MB_OK);
+
+          *cancel_default = true;      
+          return S_OK;
+        }
+
+      /* Unfortunately the Body has not yet been written to the MAPI
+         object, although the object already exists.  Thus we have to
+         take it from the OOM which requires us to rewrite parts of
+         the message encryption functions.  More work ... */
+      unknown = get_oom_iunknown (m_object, "MAPIOBJECT");
+      if (!unknown)
+        log_error ("%s:%s: error getting MAPI object", SRCNAME, __func__);
+      else
+        {
+          hr = unknown->QueryInterface (IID_IMessage, (void**)&message);
+          if (hr != S_OK || !message)
+            {
+              message = NULL;
+              log_error ("%s:%s: error getting IMESSAGE: hr=%#lx",
+                         SRCNAME, __func__, hr);
+            }
+          unknown->Release ();
+        }
+
+      if (!message)
+        rc = -1;
+      else if (encrypt && sign)
+        rc = message_sign_encrypt (message, proto, hwnd);
+      else if (encrypt && !sign)
+        rc = message_encrypt (message, proto, hwnd);
+      else if (!encrypt && sign)
+        rc = message_sign (message, proto, hwnd);
+      else
+        {
+          /* In case this is a forward message which is not to be
+             signed or encrypted we need to remove a possible body
+             attachment.  */
+          if (mapi_delete_gpgol_body_attachment (message))
+            mapi_save_changes (message, KEEP_OPEN_READWRITE);
+          rc = 0;
+        }
+      
+      if (rc)
+        {
+          *cancel_default = true;      
+          return S_OK;
+        }
+    }
 
   return S_OK;
 }
@@ -116,17 +223,34 @@ STDMETHODIMP
 GpgolItemEvents::Open (PBOOL cancel_default)
 {
   (void)cancel_default;
-  log_debug ("%s:%s: Called", SRCNAME, __func__);
+  log_debug ("%s:%s: Called (this=%p)", SRCNAME, __func__, this);
 
   return S_OK;
 }
 
+
 /* This is the event sink for a close event.  */
 STDMETHODIMP
 GpgolItemEvents::Close (PBOOL cancel_default)
 {
   (void)cancel_default;
-  log_debug ("%s:%s: Called", SRCNAME, __func__);
+  log_debug ("%s:%s: Called (this=%p)", SRCNAME, __func__, this);
+
+  /* Remove ourself.  */
+  detach_GpgolItemEvents_sink (this);
+  return S_OK;
+}
+
+
+/* This is the event Sink for a send event.  OL2003 calls this method
+   before an ECE OnSubmit.  */
+STDMETHODIMP
+GpgolItemEvents::Send (PBOOL cancel_default)
+{
+  (void)cancel_default;
+  log_debug ("%s:%s: Called (this=%p)", SRCNAME, __func__, this);
+  
+  m_send_seen = true;
 
   return S_OK;
 }
index fc13ee3..04b0da5 100644 (file)
@@ -57,14 +57,19 @@ DECLARE_INTERFACE_(IOOMItemEvents, IDispatch)
      via the IDispatch interface.  */
   /* dispid=0xf001 */
   STDMETHOD(Read)(THIS_ );
+
   /* dispid=0xf002 */
   STDMETHOD(Write)(THIS_ PBOOL cancel);
+
   /* dispid=0xf003 */
   STDMETHOD(Open)(THIS_ PBOOL cancel);
+
   /* dispid=0xf004 */
   STDMETHOD(Close)(THIS_ PBOOL cancel);
+
   /* dispid=0xf005 */
-  //STDMETHOD(Send)(THIS_ PBOOL cancel);
+  STDMETHOD(Send)(THIS_ PBOOL cancel);
+
   /* dispid=0xf006 */
   //STDMETHOD(CustomAction)(THIS_ LPDISPATCH action, LPDISPATCH response,
   //                        PBOOL cancel);
@@ -72,8 +77,11 @@ DECLARE_INTERFACE_(IOOMItemEvents, IDispatch)
   //STDMETHOD(CustomPropertyChange)(THIS_ VARIANT name);
   /* dispid=0xf009 */
   //STDMETHOD(PropertyChange)(THIS_ VARIANT name);
-  /* dispid=0xf00a */
+
+  /* dispid=0xf00a 
+     OL2003: Called between the ECE OnCheckNames and OnCheckNamesComplete.  */
   //STDMETHOD(BeforeCheckName)(THIS_ PBOOL cancel);
+
   /* dispid=0xf00b */
   //STDMETHOD(AttachmentAdd)(THIS_ LPDISPATCH att);
   /* dispid=0xf00c */
index eca0db3..4278852 100644 (file)
@@ -252,42 +252,42 @@ GpgolMessageEvents::OnWrite (LPEXCHEXTCALLBACK eecb)
 
   log_debug ("%s:%s: received\n", SRCNAME, __func__);
 
-  need_crypto = (!get_crypto_flags (eecb, &sign, &encrypt)
-                 && (sign || encrypt));
+  // need_crypto = (!get_crypto_flags (eecb, &sign, &encrypt)
+  //                && (sign || encrypt));
     
-  /* If we are going to encrypt, check that the BodyFormat is
-     something we support.  This helps avoiding surprise by sending
-     out unencrypted messages. */
-  if (need_crypto && !opt.disable_gpgol)
-    {
-      obj = get_eecb_object (eecb);
-      if (!obj)
-        bodyfmt = -1;
-      else
-        {
-          bodyfmt = get_oom_int (obj, "BodyFormat");
-          obj->Release ();
-        }
-
-      if (bodyfmt == 1)
-        m_want_html = 0;
-      else if (bodyfmt == 2)
-        m_want_html = 1;
-      else
-        {
-          log_debug ("%s:%s: BodyFormat is %d", SRCNAME, __func__, bodyfmt);
-          if (FAILED(eecb->GetWindow (&hWnd)))
-            hWnd = NULL;
-          MessageBox (hWnd,
-                      _("Sorry, we can only encrypt plain text messages and\n"
-                      "no RTF messages. Please make sure that only the text\n"
-                      "format has been selected."),
-                      "GpgOL", MB_ICONERROR|MB_OK);
-
-          m_bWriteFailed = TRUE;       
-          return E_FAIL;
-        }
-    }
+  // /* If we are going to encrypt, check that the BodyFormat is
+  //    something we support.  This helps avoiding surprise by sending
+  //    out unencrypted messages. */
+  // if (need_crypto && !opt.disable_gpgol)
+  //   {
+  //     obj = get_eecb_object (eecb);
+  //     if (!obj)
+  //       bodyfmt = -1;
+  //     else
+  //       {
+  //         bodyfmt = get_oom_int (obj, "BodyFormat");
+  //         obj->Release ();
+  //       }
+
+  //     if (bodyfmt == 1)
+  //       m_want_html = 0;
+  //     else if (bodyfmt == 2)
+  //       m_want_html = 1;
+  //     else
+  //       {
+  //         log_debug ("%s:%s: BodyFormat is %d", SRCNAME, __func__, bodyfmt);
+  //         if (FAILED(eecb->GetWindow (&hWnd)))
+  //           hWnd = NULL;
+  //         MessageBox (hWnd,
+  //                     _("Sorry, we can only encrypt plain text messages and\n"
+  //                     "no RTF messages. Please make sure that only the text\n"
+  //                     "format has been selected."),
+  //                     "GpgOL", MB_ICONERROR|MB_OK);
+
+  //         m_bWriteFailed = TRUE;    
+  //         return E_FAIL;
+  //       }
+  //   }
   
   
   return S_FALSE;
@@ -316,58 +316,58 @@ GpgolMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK eecb, ULONG flags)
   log_debug ("%s:%s: received\n", SRCNAME, __func__);
 
 
-  if (flags & (EEME_FAILED|EEME_COMPLETE_FAILED))
-    return S_FALSE; /* We don't need to rollback anything in case
-                       other extensions flagged a failure. */
+  // if (flags & (EEME_FAILED|EEME_COMPLETE_FAILED))
+  //   return S_FALSE; /* We don't need to rollback anything in case
+  //                      other extensions flagged a failure. */
 
-  if (opt.disable_gpgol)
-    return S_FALSE;
+  // if (opt.disable_gpgol)
+  //   return S_FALSE;
           
-  if (!m_bOnSubmitActive) /* The user is just saving the message. */
-    return S_FALSE;
+  // if (!m_bOnSubmitActive) /* The user is just saving the message. */
+  //   return S_FALSE;
   
-  if (m_bWriteFailed)     /* Operation failed already. */
-    return S_FALSE;
-
-  /* Try to get the current window. */
-  if (FAILED(eecb->GetWindow (&hWnd)))
-    hWnd = NULL;
-
-  /* Get the object and call the encryption or signing function.  */
-  HRESULT hr = eecb->GetObject (&pMDB, (LPMAPIPROP *)&msg);
-  if (SUCCEEDED (hr))
-    {
-      protocol_t proto = PROTOCOL_UNKNOWN; /* Let the UI server select
-                                              the protocol.  */
-      bool sign, encrypt;
-
-      if (get_crypto_flags (eecb, &sign, &encrypt))
-        rc = -1;
-      else if (encrypt && sign)
-        rc = message_sign_encrypt (msg, proto, hWnd);
-      else if (encrypt && !sign)
-        rc = message_encrypt (msg, proto, hWnd);
-      else if (!encrypt && sign)
-        rc = message_sign (msg, proto, hWnd);
-      else
-        {
-          /* In case this is a forward message which is not to be
-             signed or encrypted we need to remove a possible body
-             attachment.  */
-          if (mapi_delete_gpgol_body_attachment (msg))
-            mapi_save_changes (msg, KEEP_OPEN_READWRITE);
-          rc = 0;
-        }
+  // if (m_bWriteFailed)     /* Operation failed already. */
+  //   return S_FALSE;
+
+  // /* Try to get the current window. */
+  // if (FAILED(eecb->GetWindow (&hWnd)))
+  //   hWnd = NULL;
+
+  // /* Get the object and call the encryption or signing function.  */
+  // HRESULT hr = eecb->GetObject (&pMDB, (LPMAPIPROP *)&msg);
+  // if (SUCCEEDED (hr))
+  //   {
+  //     protocol_t proto = PROTOCOL_UNKNOWN; /* Let the UI server select
+  //                                             the protocol.  */
+  //     bool sign, encrypt;
+
+  //     if (get_crypto_flags (eecb, &sign, &encrypt))
+  //       rc = -1;
+  //     else if (encrypt && sign)
+  //       rc = message_sign_encrypt (msg, proto, hWnd);
+  //     else if (encrypt && !sign)
+  //       rc = message_encrypt (msg, proto, hWnd);
+  //     else if (!encrypt && sign)
+  //       rc = message_sign (msg, proto, hWnd);
+  //     else
+  //       {
+  //         /* In case this is a forward message which is not to be
+  //            signed or encrypted we need to remove a possible body
+  //            attachment.  */
+  //         if (mapi_delete_gpgol_body_attachment (msg))
+  //           mapi_save_changes (msg, KEEP_OPEN_READWRITE);
+  //         rc = 0;
+  //       }
       
-      if (rc)
-        {
-          hrReturn = E_FAIL;
-          m_bWriteFailed = TRUE;       
-        }
-    }
+  //     if (rc)
+  //       {
+  //         hrReturn = E_FAIL;
+  //         m_bWriteFailed = TRUE;    
+  //       }
+  //   }
   
-  ul_release (msg, __func__, __LINE__);
-  ul_release (pMDB, __func__, __LINE__);
+  // ul_release (msg, __func__, __LINE__);
+  // ul_release (pMDB, __func__, __LINE__);
   
   return hrReturn;
 }