Many more hacks.
authorWerner Koch <wk@gnupg.org>
Fri, 30 Oct 2009 21:44:43 +0000 (21:44 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 30 Oct 2009 21:44:43 +0000 (21:44 +0000)
19 files changed:
ChangeLog
src/ChangeLog
src/Makefile.am
src/attic.c [new file with mode: 0644]
src/display.cpp
src/ext-commands.cpp
src/ext-commands.h
src/inspectors.cpp
src/inspectors.h
src/message-events.cpp
src/message.cpp
src/ol-ext-callback.cpp [deleted file]
src/ol-ext-callback.h [deleted file]
src/olflange-def.h
src/olflange-dlgs.cpp
src/olflange.cpp
src/olflange.h
src/oomhelp.cpp
src/user-events.cpp

index 1e04456..d4c7221 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-10-30  Werner Koch  <wk@g10code.com>
+
+       * forms/Makefile.am (icons): Udpate all icons.
+
 2009-10-08  Werner Koch  <wk@g10code.com>
 
        * configure.ac (CFLAGS): Add -fno-strict-aliasing.
index c050737..f6fcf29 100644 (file)
@@ -1,3 +1,28 @@
+2009-10-30  Werner Koch  <wk@g10code.com>
+
+       * oomhelp.cpp (get_oom_control_bytag): Fix silly bug.
+
+       * inspectors.cpp (get_inspector_composer_flags): New.
+       (set_inspector_composer_flags): New.
+       * oomhelp.cpp (get_eecb_object): New.
+       * message-events.cpp (get_inspector): New.
+       (get_crypto_flags): New.
+       (OnWrite, OnWriteComplete): Use new functions instead of the class
+       members.  Use the new oom property functions.
+       * ext-commands.cpp (get_inspector, get_crypto_flags): New.
+       (DoCommand): Use new function.
+       (set_crypto_flags): New.
+       (InstallCommands): Use set_crypto_flags.
+       (add_menu, check_menu, add_toolbar, struct toolbar_info_s): Remove.
+       (QueryButtonInfo): Remove all code.
+       (InstallCommands): Make use of get_eecb_object and put_oom_string.
+       (DoCommand): Use get_eecb_object.
+       * olflange.h (IExchExt): Remove m_protoSelection, m_gpgSign,
+       m_gpgEncrypt and all related code.
+       * olflange.cpp (Install): Use get_oom_string.
+       * display.cpp (update_display): Ditto.
+       * ol-ext-callback.h, ol-ext-callback.cpp: Remove.
+
 2009-10-29  Werner Koch  <wk@g10code.com>
 
        * ext-commands.cpp: Remove m_nCmdDebugN, m_nCmdRevertFolder,
index 098b91e..efb023a 100644 (file)
@@ -68,7 +68,6 @@ gpgol_SOURCES = \
        attached-file-events.cpp attached-file-events.h \
        property-sheets.cpp property-sheets.h \
        item-events.h         \
-       ol-ext-callback.cpp ol-ext-callback.h \
        oomhelp.cpp oomhelp.h eventsink.h \
        explorers.cpp explorers.h \
        inspectors.cpp inspectors.h \
diff --git a/src/attic.c b/src/attic.c
new file mode 100644 (file)
index 0000000..1218eaa
--- /dev/null
@@ -0,0 +1,147 @@
+/* Check whether the preview pane is visisble.  Returns:
+   -1 := Don't know.
+    0 := No
+    1 := Yes.
+ */
+int
+is_preview_pane_visible (LPEXCHEXTCALLBACK eecb)
+{
+  HRESULT hr;      
+  LPDISPATCH pDisp;
+  DISPID dispid;
+  DISPPARAMS dispparams;
+  VARIANT aVariant, rVariant;
+      
+  pDisp = find_outlook_property (eecb,
+                                 "Application.ActiveExplorer.IsPaneVisible",
+                                 &dispid);
+  if (!pDisp)
+    {
+      log_debug ("%s:%s: ActiveExplorer.IsPaneVisible NOT found\n",
+                 SRCNAME, __func__);
+      return -1;
+    }
+
+  dispparams.rgvarg = &aVariant;
+  dispparams.rgvarg[0].vt = VT_INT;
+  dispparams.rgvarg[0].intVal = 3; /* olPreview */
+  dispparams.cArgs = 1;
+  dispparams.cNamedArgs = 0;
+  rVariant.bstrVal = NULL;
+  hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
+                      DISPATCH_METHOD, &dispparams,
+                      &rVariant, NULL, NULL);
+  pDisp->Release();
+  pDisp = NULL;
+  if (hr == S_OK && rVariant.vt != VT_BOOL)
+    {
+      log_debug ("%s:%s: invoking IsPaneVisible succeeded but vt is %d",
+                 SRCNAME, __func__, rVariant.vt);
+      if (rVariant.vt == VT_BSTR && rVariant.bstrVal)
+        SysFreeString (rVariant.bstrVal);
+      return -1;
+    }
+  if (hr != S_OK)
+    {
+      log_debug ("%s:%s: invoking IsPaneVisible failed: %#lx",
+                 SRCNAME, __func__, hr);
+      return -1;
+    }
+  
+  return !!rVariant.boolVal;
+  
+}
+
+
+/* Set the preview pane to visible if visble is true or to invisible
+   if visible is false.  */
+void
+show_preview_pane (LPEXCHEXTCALLBACK eecb, int visible)
+{
+  HRESULT hr;      
+  LPDISPATCH pDisp;
+  DISPID dispid;
+  DISPPARAMS dispparams;
+  VARIANT aVariant[2];
+      
+  pDisp = find_outlook_property (eecb,
+                                 "Application.ActiveExplorer.ShowPane",
+                                 &dispid);
+  if (!pDisp)
+    {
+      log_debug ("%s:%s: ActiveExplorer.ShowPane NOT found\n",
+                 SRCNAME, __func__);
+      return;
+    }
+
+  dispparams.rgvarg = aVariant;
+  dispparams.rgvarg[0].vt = VT_BOOL;
+  dispparams.rgvarg[0].boolVal = !!visible;
+  dispparams.rgvarg[1].vt = VT_INT;
+  dispparams.rgvarg[1].intVal = 3; /* olPreview */
+  dispparams.cArgs = 2;
+  dispparams.cNamedArgs = 0;
+  hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
+                      DISPATCH_METHOD, &dispparams,
+                      NULL, NULL, NULL);
+  pDisp->Release();
+  pDisp = NULL;
+  if (hr != S_OK)
+    log_debug ("%s:%s: invoking ShowPane(%d) failed: %#lx",
+               SRCNAME, __func__, visible, hr);
+}
+
+
+/***
+Outlook interop – stopping user properties appearing on Outlook message print
+
+Here’s a weird one… we were adding user properties to a message using the IUserProperties interface, but whenever we did this the property would render when the message was printed. This included whenever the message was sent to a recipient within the same Exchange organisation.
+
+Last time I had to ask Microsoft PSS to help was 1992, and in that case they were nice enough to send me a handcrafted sample application on a 3.5″ floppy. This time however they got back to me in a day with this little code snippet:
+
+void MarkPropNoPrint(Outlook.MailItem message, string propertyName)
+{
+// Late Binding in .NET
+// http://support.microsoft.com/default.aspx?scid=kb;EN-US;302902
+Type userPropertyType;
+long dispidMember = 107;
+long ulPropPrintable = 0×4;
+string dispMemberName = String.Format(”[DispID={0}]“, dispidMember);
+object[] dispParams;
+Microsoft.Office.Interop.Outlook.UserProperty userProperty = message.UserProperties[propertyName];
+
+if (null == userProperty) return;
+userPropertyType = userProperty.GetType();
+
+// Call IDispatch::Invoke to get the current flags
+object flags = userPropertyType.InvokeMember(dispMemberName, System.Reflection.BindingFlags.GetProperty, null, userProperty, null);
+long lFlags = long.Parse(flags.ToString());
+
+// Remove the hidden property Printable flag
+lFlags &= ~ulPropPrintable;
+
+// Place the new flags property into an argument array
+dispParams = new object[] {lFlags};
+
+// Call IDispatch::Invoke to set the current flags
+userPropertyType.InvokeMember(dispMemberName,
+System.Reflection.BindingFlags.SetProperty, null, userProperty, dispParams);
+}
+
+Srsly… there is no way I would have worked that out for myself…
+
+*/
+
+
+
+/* HOWTO get the Window handle */
+
+/* Use FindWindow. Use the Inspector.Caption property (be aware that on long */
+/* captions the result will be truncated at about 255 characters). The class */
+/* name to use for the Inspector window is "rctrl_renwnd32". */
+
+/* I usually set any dialogs as modal to the Inspector window using */
+/* SetWindowLong, then the dialog would end up in front of the mail window, */
+/* which would be in front of the Outlook Explorer window. */
+
+
index ff1ebb0..1b8b9e3 100644 (file)
@@ -29,7 +29,7 @@
 #include "myexchext.h"
 #include "common.h"
 #include "mapihelp.h"
-#include "ol-ext-callback.h"
+#include "olflange-def.h"
 #include "display.h"
 
 
@@ -222,7 +222,6 @@ update_display (HWND hwnd, void *exchange_cb, int is_sensitive,
   struct find_message_window_state findstate;
 
   (void)is_sensitive;
-  
 
   memset (&findstate, 0, sizeof findstate);
   window = find_message_window (hwnd, &findstate);
@@ -246,29 +245,33 @@ update_display (HWND hwnd, void *exchange_cb, int is_sensitive,
         SetWindowTextA (window, text);
       return 0;
     }
-//   else if (exchange_cb && is_sensitive && !opt.compat.no_oom_write)
-//     {
-//       log_debug ("%s:%s: updating display using OOM (note)\n", 
-//                  SRCNAME, __func__);
-//       if (is_html)
-//         put_outlook_property (exchange_cb, "Body", "" );
-//       return put_outlook_property
-//         (exchange_cb, "Body",
-//          _("[Encrypted body not shown - please open the message]"));
-//     }
   else if (exchange_cb && !opt.compat.no_oom_write)
     {
+      LPDISPATCH obj;
+      int rc;
+
       log_debug ("%s:%s: updating display using OOM\n", SRCNAME, __func__);
-      /* Bug in OL 2002 and 2003 - as a workaround set the body first
-         to empty. */
+      
+      obj = get_eecb_object ((LPEXCHEXTCALLBACK)exchange_cb);
+      if (!obj)
+        {
+          log_error ("%s:%s: Object not found via EECB\n", SRCNAME, __func__);
+          return -1;
+        }
+
       if (is_html)
-        put_outlook_property (exchange_cb, "Body", "" );
-      return put_outlook_property (exchange_cb, is_html? "HTMLBody":"Body",
-                                 text);
+        {
+          /* Bug in OL 2002 and 2003 - as a workaround set the body
+             first to empty. */
+          put_oom_string (obj, "Body", "");
+        }
+      rc = put_oom_string (obj, is_html? "HTMLBody":"Body", text);
+      obj->Release ();
+      return rc;
     }
   else
     {
-      log_debug ("%s:%s: window handle not found for parent %p\n",
+      log_error ("%s:%s: window handle not found for parent %p\n",
                  SRCNAME, __func__, hwnd);
       return -1;
     }
index 4de6c28..3fc079b 100644 (file)
 #include "dialogs.h"       /* For IDB_foo. */
 #include "olflange-def.h"
 #include "olflange.h"
-#include "ol-ext-callback.h"
 #include "message.h"
 #include "engine.h"
 #include "revert.h"
 #include "ext-commands.h"
 #include "explorers.h"
+#include "inspectors.h"
 
 #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \
                                      SRCNAME, __func__, __LINE__); \
                         } while (0)
 
-/* An object to store information about active (installed) toolbar
-   buttons.  */
-struct toolbar_info_s
-{
-  toolbar_info_t next;
-
-  UINT button_id;/* The ID of the button as assigned by Outlook.  */
-  UINT bitmap;   /* The bitmap of the button.  */
-  UINT cmd_id;   /* The ID of the command to send on a click.  */
-  const char *desc;/* The description text.  */
-  ULONG context; /* Context under which this entry will be used.  */ 
-  int did_qbi;   /* Has been processed by QueryButtonInfo.  */
-};
-
 
 /* Keep copies of some bitmaps.  */
 static int bitmaps_initialized;
 static HBITMAP my_check_bitmap, my_uncheck_bitmap;
 
 
-
-static void add_menu (LPEXCHEXTCALLBACK eecb, 
-                      UINT FAR *pnCommandIDBase, ...)
-#if __GNUC__ >= 4 
-                               __attribute__ ((sentinel))
-#endif
-  ;
-
-
-
-
 /* Wrapper around UlRelease with error checking. */
 static void 
 ul_release (LPVOID punk, const char *func, int lnr)
@@ -99,7 +74,6 @@ GpgolExtCommands::GpgolExtCommands (GpgolExt* pParentInterface)
   m_pExchExt = pParentInterface; 
   m_lRef = 0; 
   m_lContext = 0; 
-    m_toolbar_info = NULL; 
   m_hWnd = NULL; 
 
   if (!bitmaps_initialized)
@@ -113,12 +87,7 @@ GpgolExtCommands::GpgolExtCommands (GpgolExt* pParentInterface)
 /* Destructor */
 GpgolExtCommands::~GpgolExtCommands (void)
 {
-  while (m_toolbar_info)
-    {
-      toolbar_info_t tmp = m_toolbar_info->next;
-      xfree (m_toolbar_info);
-      m_toolbar_info = tmp;
-    }
+
 }
 
 
@@ -136,142 +105,64 @@ GpgolExtCommands::QueryInterface (REFIID riid, LPVOID FAR * ppvObj)
 }
 
 
-/* Add a new menu.  The variable entries are made up of pairs of
-   strings and UINT *.  A NULL is used to terminate this list.  An
-   empty string is translated to a separator menu item.  One level of
-   submenus are supported. */
-static void
-add_menu (LPEXCHEXTCALLBACK eecb, UINT FAR *pnCommandIDBase, ...)
+/* Note: Duplicated from message-events.cpp.  Eventually we should get
+   rid of this module.  */
+static LPDISPATCH
+get_inspector (LPEXCHEXTCALLBACK eecb)
 {
-  va_list arg_ptr;
-  HMENU mainmenu, submenu, menu;
-  const char *string;
-  UINT *cmdptr;
+  LPDISPATCH obj;
+  LPDISPATCH inspector = NULL;
   
-  va_start (arg_ptr, pnCommandIDBase);
-  /* We put all new entries into the tools menu.  To make this work we
-     need to pass the id of an existing item from that menu.  */
-  eecb->GetMenuPos (EECMDID_ToolsCustomizeToolbar, &mainmenu, NULL, NULL, 0);
-  menu = mainmenu;
-  submenu = NULL;
-  while ( (string = va_arg (arg_ptr, const char *)) )
+  obj = get_eecb_object (eecb);
+  if (obj)
     {
-      cmdptr = va_arg (arg_ptr, UINT*);
-
-      if (!*string)
-        ; /* Ignore this entry.  */
-      else if (*string == '@' && !string[1])
-        AppendMenu (menu, MF_SEPARATOR, 0, NULL);
-      else if (*string == '>')
-        {
-          submenu = CreatePopupMenu ();
-          AppendMenu (menu, MF_STRING|MF_POPUP, (UINT_PTR)submenu, string+1);
-          menu = submenu;
-        }
-      else if (*string == '<')
-        {
-          menu = mainmenu;
-          submenu = NULL;
-        }
-      else
-       {
-          AppendMenu (menu, MF_STRING, *pnCommandIDBase, string);
-          if (menu == submenu)
-            SetMenuItemBitmaps (menu, *pnCommandIDBase, MF_BYCOMMAND,
-                                my_uncheck_bitmap, my_check_bitmap);
-          if (cmdptr)
-            *cmdptr = *pnCommandIDBase;
-          (*pnCommandIDBase)++;
-        }
+      /* This should be MailItem; use the getInspector method.  */
+      inspector = get_oom_object (obj, "GetInspector");
+      obj->Release ();
     }
-  va_end (arg_ptr);
+  return inspector;
 }
 
 
-static void
-check_menu (LPEXCHEXTCALLBACK eecb, UINT menu_id, int checked)
+/* Note: Duplicated from message-events.cpp.  Eventually we should get
+   rid of this module.  */
+static int
+get_crypto_flags (LPEXCHEXTCALLBACK eecb, bool *r_sign, bool *r_encrypt)
 {
-  HMENU menu;
-
-  eecb->GetMenuPos (EECMDID_ToolsCustomizeToolbar, &menu, NULL, NULL, 0);
-  if (debug_commands)
-    log_debug ("check_menu: eecb=%p menu_id=%u checked=%d -> menu=%p\n", 
-               eecb, menu_id, checked, menu);
-  CheckMenuItem (menu, menu_id, 
-                 MF_BYCOMMAND | (checked?MF_CHECKED:MF_UNCHECKED));
-}
-
-
-
-void
-GpgolExtCommands::add_toolbar (LPTBENTRY tbearr, UINT n_tbearr, ...)
-{
-  va_list arg_ptr;
-  const char *desc;
-  UINT bmapid;
-  UINT cmdid;
-  int tbeidx;
-  toolbar_info_t tb_info;
+  LPDISPATCH inspector;
   int rc;
 
-  for (tbeidx = n_tbearr-1; tbeidx > -1; tbeidx--)
-    if (tbearr[tbeidx].tbid == EETBID_STANDARD)
-      break;
-  if (!(tbeidx > -1))
+  inspector = get_inspector (eecb);
+  if (!inspector)
     {
-      log_error ("standard toolbar not found");
-      return;
+      log_error ("%s:%s: inspector not found", SRCNAME, __func__);
+      rc = -1;
     }
-  
-  SendMessage (tbearr[tbeidx].hwnd, TB_BUTTONSTRUCTSIZE,
-               (WPARAM)(int)sizeof (TBBUTTON), 0);
+  else
+    {
+      rc = get_inspector_composer_flags (inspector, r_sign, r_encrypt);
+      inspector->Release ();
+    }
+  return rc;
+}
 
-  
-  va_start (arg_ptr, n_tbearr);
 
-  while ( (desc = va_arg (arg_ptr, const char *)) )
-    {
-      bmapid = va_arg (arg_ptr, UINT);
-      cmdid = va_arg (arg_ptr, UINT);
+static void
+set_crypto_flags (LPEXCHEXTCALLBACK eecb, bool sign, bool encrypt)
+{
+  LPDISPATCH inspector;
 
-      if (!*desc)
-        ; /* Empty description - ignore this item.  */
-      else if (*desc == '|' && !desc[1])
-        {
-          /* Separator. Ignore BMAPID and CMDID.  */
-          /* Not yet implemented.  */
-        }
-      else
-       {
-          TBADDBITMAP tbab;
-  
-          tb_info = (toolbar_info_t)xcalloc (1, sizeof *tb_info);
-          tb_info->button_id = tbearr[tbeidx].itbbBase++;
-
-          tbab.hInst = glob_hinst;
-          tbab.nID = bmapid;
-          rc = SendMessage (tbearr[tbeidx].hwnd, TB_ADDBITMAP,1,(LPARAM)&tbab);
-          if (rc == -1)
-            log_error_w32 (-1, "TB_ADDBITMAP failed for `%s'", desc);
-          tb_info->bitmap = rc;
-          tb_info->cmd_id = cmdid;
-          tb_info->desc = desc;
-          tb_info->context = m_lContext;
-
-          tb_info->next = m_toolbar_info;
-          m_toolbar_info = tb_info;
-          if (debug_commands)
-            log_debug ("%s:%s: ctx=%lx button_id=%d cmd_id=%d '%s'\n", 
-                       SRCNAME, __func__, m_lContext,
-                       tb_info->button_id, tb_info->cmd_id, tb_info->desc);
-        }
+  inspector = get_inspector (eecb);
+  if (!inspector)
+    log_error ("%s:%s: inspector not found", SRCNAME, __func__);
+  else
+    {
+      set_inspector_composer_flags (inspector, sign, encrypt);
+      inspector->Release ();
     }
-  va_end (arg_ptr);
-
 }
 
 
-
 /* Called by Exchange to install commands and toolbar buttons.  Returns
    S_FALSE to signal Exchange to continue calling extensions. */
 STDMETHODIMP 
@@ -287,14 +178,7 @@ GpgolExtCommands::InstallCommands (
 {
   HRESULT hr;
   m_hWnd = hWnd;
-  LPDISPATCH pDisp;
-  DISPID dispid;
-  DISPID dispid_put = DISPID_PROPERTYPUT;
-  DISPPARAMS dispparams;
-  VARIANT aVariant;
-  int force_encrypt = 0;
-  char *draft_info = NULL;
-  
+  LPDISPATCH obj;
 
   (void)hMenu;
   
@@ -302,7 +186,6 @@ GpgolExtCommands::InstallCommands (
     log_debug ("%s:%s: context=%s flags=0x%lx\n", SRCNAME, __func__, 
                ext_context_name (m_lContext), lFlags);
 
-  show_event_object (eecb, __func__);
 
   /* Outlook 2003 sometimes displays the plaintext and sometimes the
      original undecrypted text when doing a reply.  This seems to
@@ -326,6 +209,8 @@ GpgolExtCommands::InstallCommands (
     {
       LPMDB mdb = NULL;
       LPMESSAGE message = NULL;
+      int force_encrypt = 0;
+      char *draft_info = NULL;
       
       /*  Note that for read and send the object returned by the
           outlook extension callback is of class 43 (MailItem) so we
@@ -335,72 +220,38 @@ GpgolExtCommands::InstallCommands (
         log_debug ("%s:%s: getObject failed: hr=%#lx\n", SRCNAME,__func__,hr);
       else if (!opt.compat.no_msgcache)
         {
-          const char *body;
-          char *key = NULL;
-          size_t keylen = 0;
-          void *refhandle = NULL;
-     
-          pDisp = find_outlook_property (eecb, "ConversationIndex", &dispid);
-          if (pDisp)
+          obj = get_eecb_object (eecb);
+          if (obj)
             {
-              DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
-
-              aVariant.bstrVal = NULL;
-              hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                                  DISPATCH_PROPERTYGET, &dispparamsNoArgs,
-                                  &aVariant, NULL, NULL);
-              if (hr != S_OK)
-                log_debug ("%s:%s: retrieving ConversationIndex failed: %#lx",
-                           SRCNAME, __func__, hr);
-              else if (aVariant.vt != VT_BSTR)
-                log_debug ("%s:%s: ConversationIndex is not a string (%d)",
-                           SRCNAME, __func__, aVariant.vt);
-              else if (aVariant.bstrVal)
-                {
-                  char *p;
+              const char *body;
+              char *key, *p;
+              size_t keylen;
+              void *refhandle = NULL;
 
-                  key = wchar_to_utf8 (aVariant.bstrVal);
+              key = get_oom_string (obj, "ConversationIndex");
+              if (key)
+                {
                   log_debug ("%s:%s: ConversationIndex is `%s'",
-                           SRCNAME, __func__, key);
+                             SRCNAME, __func__, key);
                   /* The key is a hex string.  Convert it to binary. */
                   for (keylen=0,p=key; hexdigitp(p) && hexdigitp(p+1); p += 2)
                     ((unsigned char*)key)[keylen++] = xtoi_2 (p);
                   
-                 SysFreeString (aVariant.bstrVal);
+                  if (keylen && (body = msgcache_get (key, keylen, &refhandle)))
+                    {
+                      put_oom_string (obj, "Body", body);
+                      /* Because we found the plaintext in the cache
+                         we can assume that the orginal message has
+                         been encrypted and thus we now set a flag to
+                         make sure that by default the reply gets
+                         encrypted too. */
+                      force_encrypt = 1;
+                    }
+                  msgcache_unref (refhandle);
+                  xfree (key);
                 }
-
-              pDisp->Release();
-              pDisp = NULL;
-            }
-          
-          if (key && keylen
-              && (body = msgcache_get (key, keylen, &refhandle)) 
-              && (pDisp = find_outlook_property (eecb, "Body", &dispid)))
-            {
-              dispparams.cNamedArgs = 1;
-              dispparams.rgdispidNamedArgs = &dispid_put;
-              dispparams.cArgs = 1;
-              dispparams.rgvarg = &aVariant;
-              dispparams.rgvarg[0].vt = VT_LPWSTR;
-              dispparams.rgvarg[0].bstrVal = utf8_to_wchar (body);
-              hr = pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                                 DISPATCH_PROPERTYPUT, &dispparams,
-                                 NULL, NULL, NULL);
-              xfree (dispparams.rgvarg[0].bstrVal);
-              log_debug ("%s:%s: PROPERTYPUT(body) result -> %#lx\n",
-                         SRCNAME, __func__, hr);
-
-              pDisp->Release();
-              pDisp = NULL;
-              
-              /* Because we found the plaintext in the cache we can assume
-                 that the orginal message has been encrypted and thus we
-                 now set a flag to make sure that by default the reply
-                 gets encrypted too. */
-              force_encrypt = 1;
+              obj->Release ();
             }
-          msgcache_unref (refhandle);
-          xfree (key);
         }
       
       /* Because we have the message open, we use it to get the draft
@@ -408,43 +259,36 @@ GpgolExtCommands::InstallCommands (
       if (message)
         draft_info = mapi_get_gpgol_draft_info (message);
 
-
       ul_release (message, __func__, __LINE__);
       ul_release (mdb, __func__, __LINE__);
+      
+      if (!opt.disable_gpgol) 
+        {
+          bool sign, encrypt;
+          
+          if (draft_info && draft_info[0] == 'E')
+            encrypt = true;
+          else if (draft_info && draft_info[0] == 'e')
+            encrypt = false;
+          else
+            encrypt = !!opt.encrypt_default;
+          
+          if (draft_info && draft_info[0] && draft_info[1] == 'S')
+            sign = true;
+          else if (draft_info && draft_info[0] && draft_info[1] == 's')
+            sign = false;
+          else
+            sign = !!opt.sign_default;
+          
+          if (force_encrypt)
+            encrypt = true;
+          
+          /* FIXME:  ove that to the inspector activation.  */
+          //set_crypto_flags (eecb, sign, encrypt);
+        }
+      xfree (draft_info);
     }
 
-  /* Now install menu and toolbar items.  */
-  if (m_lContext == EECONTEXT_READNOTEMESSAGE)
-    {
-    }
-  else if (m_lContext == EECONTEXT_SENDNOTEMESSAGE && !opt.disable_gpgol) 
-    {
-      m_pExchExt->m_protoSelection = opt.default_protocol;
-
-      if (draft_info && draft_info[0] == 'E')
-        m_pExchExt->m_gpgEncrypt = true;
-      else if (draft_info && draft_info[0] == 'e')
-        m_pExchExt->m_gpgEncrypt = false;
-      else
-        m_pExchExt->m_gpgEncrypt = opt.encrypt_default;
-
-      if (draft_info && draft_info[0] && draft_info[1] == 'S')
-        m_pExchExt->m_gpgSign = true;
-      else if (draft_info && draft_info[0] && draft_info[1] == 's')
-        m_pExchExt->m_gpgSign = false;
-      else
-        m_pExchExt->m_gpgSign = opt.sign_default;
-
-      if (force_encrypt)
-        m_pExchExt->m_gpgEncrypt = true;
-    }
-  else if (m_lContext == EECONTEXT_VIEWER) 
-    {
-
-    }
-
-  xfree (draft_info);
-
   return S_FALSE;
 }
 
@@ -467,8 +311,6 @@ GpgolExtCommands::DoCommand (LPEXCHEXTCALLBACK eecb, UINT nCommandID)
                SRCNAME, __func__, nCommandID, nCommandID, 
                ext_context_name (m_lContext), hwnd);
 
-  show_event_object (eecb, __func__);
-
   if (nCommandID == SC_CLOSE && m_lContext == EECONTEXT_READNOTEMESSAGE)
     {
       /* This is the system close command. Replace it with our own to
@@ -477,14 +319,16 @@ GpgolExtCommands::DoCommand (LPEXCHEXTCALLBACK eecb, UINT nCommandID)
          own OOM (in this case Body). */
       LPDISPATCH pDisp;
       DISPID dispid;
-      DISPPARAMS dispparams;
-      VARIANT aVariant;
       
       if (debug_commands)
         log_debug ("%s:%s: command Close called\n", SRCNAME, __func__);
-      pDisp = find_outlook_property (eecb, "Close", &dispid);
-      if (pDisp)
+      
+      pDisp = get_eecb_object (eecb);
+      dispid = lookup_oom_dispid (pDisp, "Close");
+      if (pDisp && dispid != DISPID_UNKNOWN)
         {
+          DISPPARAMS dispparams;
+          VARIANT aVariant;
           /* Note that there is a report on the Net from 2005 by Amit
              Joshi where he claims that in Outlook XP olDiscard does
              not work but is treated like olSave.  */ 
@@ -509,8 +353,12 @@ GpgolExtCommands::DoCommand (LPEXCHEXTCALLBACK eecb, UINT nCommandID)
                      SRCNAME, __func__, hr);
         }
       else
-        log_debug ("%s:%s: invoking Close failed: no Close method)",
-                   SRCNAME, __func__);
+        {
+          if (pDisp)
+            pDisp->Release ();
+          log_debug ("%s:%s: invoking Close failed: no Close method)",
+                     SRCNAME, __func__);
+        }
 
       message_wipe_body_cruft (eecb);
 
@@ -542,17 +390,18 @@ GpgolExtCommands::DoCommand (LPEXCHEXTCALLBACK eecb, UINT nCommandID)
            && m_lContext == EECONTEXT_SENDNOTEMESSAGE) 
     {
       char buf[4];
+      bool sign, encrypt;
       
       log_debug ("%s:%s: command SaveMessage called\n", SRCNAME, __func__);
-      buf[0] = m_pExchExt->m_gpgEncrypt? 'E':'e';
-      buf[1] = m_pExchExt->m_gpgSign? 'S':'s';
-      switch (m_pExchExt->m_protoSelection)
+
+      if (get_crypto_flags (eecb, &sign, &encrypt))
+        buf[0] = buf[1] = '?';
+      else
         {
-        case PROTOCOL_UNKNOWN: buf[2] = 'A'; break;
-        case PROTOCOL_OPENPGP: buf[2] = 'P'; break;
-        case PROTOCOL_SMIME:   buf[2] = 'X'; break;
-        default: buf[2] = '-'; break;
+          buf[0] = encrypt? 'E':'e';
+          buf[1] = sign?    'S':'s';
         }
+      buf[2] = 'A'; /* Automatic.  */
       buf[3] = 0;
 
       hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
@@ -595,8 +444,7 @@ STDMETHODIMP
 GpgolExtCommands::Help (LPEXCHEXTCALLBACK eecb, UINT nCommandID)
 {
   (void)eecb;
-
-  show_event_object (eecb, __func__);
+  (void)nCommandID;
 
   return S_FALSE;
 }
@@ -634,42 +482,10 @@ GpgolExtCommands::QueryButtonInfo (ULONG toolbarid, UINT buttonid,
                                    LPTSTR description, UINT description_size,
                                    ULONG flags)          
 {
-  toolbar_info_t tb_info;
-  size_t n;
-  
-
   (void)description_size;
   (void)flags;
 
-  for (tb_info = m_toolbar_info; tb_info; tb_info = tb_info->next )
-    if (tb_info->button_id == buttonid
-        && tb_info->context == m_lContext)
-      break;
-  if (!tb_info)
-    return S_FALSE; /* Not one of our toolbar buttons.  */
-
-  if (debug_commands)
-    log_debug ("%s:%s: ctx=%lx tbid=%ld button_id(req)=%d got=%d"
-               " cmd_id=%d '%s'\n", 
-               SRCNAME, __func__, m_lContext, toolbarid, buttonid,
-               tb_info->button_id, tb_info->cmd_id, tb_info->desc);
-
-  /* Mark that this button has passed this function.  */
-  tb_info->did_qbi = 1;
-  
-  pTBB->iBitmap = tb_info->bitmap;
-  pTBB->idCommand = tb_info->cmd_id;
-  pTBB->fsState = TBSTATE_ENABLED;
-  pTBB->fsStyle = TBSTYLE_BUTTON;
-  pTBB->dwData = 0;
-  pTBB->iString = -1;
-  
-  n = strlen (tb_info->desc);
-  if (n > description_size)
-    n = description_size;
-  lstrcpyn (description, tb_info->desc, n);
-
-  return S_OK;
+  return S_FALSE; /* Not one of our toolbar buttons.  */
 }
 
 
index 903c103..cbc13ee 100644 (file)
@@ -40,16 +40,10 @@ private:
   ULONG m_lRef;
   ULONG m_lContext;
   
-  /* A list of all active toolbar items.  */
-  toolbar_info_t m_toolbar_info;
-  
   HWND  m_hWnd;
   
   GpgolExt* m_pExchExt;
 
-  void add_toolbar (LPTBENTRY tbearr, UINT n_tbearr, ...);
-  void update_protocol_menu (LPEXCHEXTCALLBACK eecb);
-  
 public:
   STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj);
   inline STDMETHODIMP_(ULONG) AddRef (void)
index ed80acc..08cf80d 100644 (file)
@@ -64,11 +64,15 @@ END_EVENT_SINK(GpgolInspectorsEvents, IID_IOOMInspectorsEvents)
 
 \f
 /* Event sink for an Inspector object.  */
+typedef struct GpgolInspectorEvents GpgolInspectorEvents;
+typedef GpgolInspectorEvents *LPGPGOLINSPECTOREVENTS;
+
 BEGIN_EVENT_SINK(GpgolInspectorEvents, IOOMInspectorEvents)
   STDMETHOD_ (void, Activate) (THIS_);
   STDMETHOD_ (void, Close) (THIS_);
   STDMETHOD_ (void, Deactivate) (THIS_);
   bool m_first_activate_seen;
+  unsigned long m_serialno;
 EVENT_SINK_CTOR(GpgolInspectorEvents)
 {
   m_first_activate_seen = false;
@@ -105,6 +109,7 @@ END_EVENT_SINK(GpgolInspectorEvents, IID_IOOMInspectorEvents)
 struct button_list_s
 {
   struct button_list_s *next;
+  unsigned long serialno; /* of the inspector.  */
   LPDISPATCH sink;
   LPDISPATCH button;
   int instid;
@@ -124,6 +129,9 @@ struct inspector_info_s
   /* The inspector object.  */
   LPOOMINSPECTOR inspector;
 
+  /* Our serial number for the inspector.  */
+  unsigned long serialno;
+
   /* The event sink object.  This is used by the event methods to
      locate the inspector object.  */
   LPOOMINSPECTOREVENTS eventsink;
@@ -139,6 +147,8 @@ static inspector_info_t all_inspectors;
 static HANDLE all_inspectors_lock;
 
 
+static void add_inspector_controls (LPOOMINSPECTOR inspector, 
+                                    unsigned long serialno);
 static void update_crypto_info (LPDISPATCH button);
 
 
@@ -187,12 +197,30 @@ unlock_all_inspectors (void)
 }
 
 
+/* Return a new serial number for an inspector.  These serial numbers
+   are used to make the button tags unique.  */
+static unsigned long
+create_inspector_serial (void)
+{
+  static long serial;
+  long n;
+
+  /* Avoid returning 0 because we use that value as Nil.  */
+  while (!(n = InterlockedIncrement (&serial)))
+    ;
+  return (unsigned long)n;
+}
+
+
 /* Add SINK and BUTTON to the list at LISTADDR.  The list takes
    ownership of SINK and BUTTON, thus the caller may not use OBJ or
-   OBJ2 after this call.  If TAG is given it is stored as well.  */
+   OBJ2 after this call.  If TAG must be given without the
+   serialnumber suffix.  SERIALNO is the serialno of the correspnding
+   inspector.  */
 static void
 move_to_button_list (button_list_t *listaddr, 
-                     LPDISPATCH sink, LPDISPATCH button, const char *tag)
+                     LPDISPATCH sink, LPDISPATCH button, 
+                     const char *tag, unsigned long serialno)
 {
   button_list_t item;
   int instid;
@@ -202,13 +230,14 @@ move_to_button_list (button_list_t *listaddr,
 
   instid = button? get_oom_int (button, "InstanceId"): 0;
 
-  // log_debug ("%s:%s: sink=%p btn=%p tag=(%s) instid=%d",
-  //            SRCNAME, __func__, sink, button, tag, instid);
+  log_debug ("%s:%s: sink=%p btn=%p tag=(%s) instid=%d",
+             SRCNAME, __func__, sink, button, tag, instid);
 
   item = (button_list_t)xcalloc (1, sizeof *item + strlen (tag));
   item->sink = sink;
   item->button = button;
   item->instid = instid;
+  item->serialno = serialno;
   strcpy (item->tag, tag);
   item->next = *listaddr;
   *listaddr = item;
@@ -217,7 +246,7 @@ move_to_button_list (button_list_t *listaddr,
 
 /* Register the inspector object INSPECTOR along with its event SINK.  */
 static void
-register_inspector (LPOOMINSPECTOR inspector, LPOOMINSPECTOREVENTS sink)
+register_inspector (LPOOMINSPECTOR inspector, LPGPGOLINSPECTOREVENTS sink)
 {
   inspector_info_t item;
 
@@ -225,6 +254,7 @@ register_inspector (LPOOMINSPECTOR inspector, LPOOMINSPECTOREVENTS sink)
   lock_all_inspectors ();
   inspector->AddRef ();
   item->inspector = inspector;
+  item->serialno = sink->m_serialno = create_inspector_serial ();
 
   sink->AddRef ();
   item->eventsink = sink;
@@ -303,6 +333,65 @@ get_inspector_info (LPOOMINSPECTOR inspector)
 }
 
 
+/* Return the serialno of INSPECTOR or 0 if not found.  */
+static unsigned long
+get_serialno (LPDISPATCH inspector)
+{
+  unsigned int result = 0;
+  inspector_info_t iinfo;
+
+  /* FIXME: This might not bet reliable.  We merely compare the
+     pointer and not something like an Instance Id.  We should check
+     whether this is sufficient or whether to track the inspectors
+     with different hack.  For example we could add an invisible menu
+     entry and scan for that entry to get the serial number serial
+     number of it.  A better option would be to add a custom property
+     to the inspector, but that seems not supported - we could of
+     course add it to a button then. */ 
+  lock_all_inspectors ();
+
+  for (iinfo = all_inspectors; iinfo; iinfo = iinfo->next)
+    if (iinfo->inspector == inspector)
+      {
+        result = iinfo->serialno;
+        break;
+      }
+
+  unlock_all_inspectors ();
+  return result;
+}
+
+
+/* Return the button with TAG and assigned to the isnpector with
+   SERIALNO.  Return NULL if not found.  */
+static LPDISPATCH
+get_button (unsigned long serialno, const char *tag)
+{
+  LPDISPATCH result = NULL;
+  inspector_info_t iinfo;
+  button_list_t ol;
+
+  lock_all_inspectors ();
+
+  for (iinfo = all_inspectors; iinfo; iinfo = iinfo->next)
+    if (iinfo->serialno == serialno)
+      {
+        for (ol = iinfo->buttons; ol; ol = ol->next)
+          if (ol->tag && !strcmp (ol->tag, tag))
+            {
+              result = ol->button;
+              if (result)
+                result->AddRef ();
+              break;
+            }
+        break;
+      }
+  
+  unlock_all_inspectors ();
+  return result;
+}
+
+
 /* Search through all objects and find the inspector which has a
    button with the instanceId INSTID.  The find the button with TAG in
    that inspector and return it.  Caller must release the returned
@@ -315,7 +404,7 @@ get_button_by_instid_and_tag (int instid, const char *tag)
   button_list_t ol;
 
   // log_debug ("%s:%s: inst=%d tag=(%s)",SRCNAME, __func__, instid, tag);
-
+  
   lock_all_inspectors ();
 
   for (iinfo = all_inspectors; iinfo; iinfo = iinfo->next)
@@ -340,6 +429,7 @@ get_button_by_instid_and_tag (int instid, const char *tag)
 
 
 
+
 /* The method called by outlook for each new inspector.  Note that
    Outlook sometimes reuses Inspectro objects thus this event is not
    an indication for a newly opened Inspector.  */
@@ -356,7 +446,7 @@ GpgolInspectorsEvents::NewInspector (LPOOMINSPECTOR inspector)
   obj = install_GpgolInspectorEvents_sink ((LPDISPATCH)inspector);
   if (obj)
     {
-      register_inspector (inspector, (LPOOMINSPECTOREVENTS)obj);
+      register_inspector (inspector, (LPGPGOLINSPECTOREVENTS)obj);
       obj->Release ();
     }
   inspector->Release ();
@@ -402,16 +492,16 @@ GpgolInspectorEvents::Activate (void)
   if (!m_first_activate_seen)
     {
       m_first_activate_seen = true;
-      add_inspector_controls (inspector);
+      add_inspector_controls (inspector, m_serialno);
     }
   
   /* Update the crypt info.  */
-  obj = get_oom_object (m_object, "CommandBars");
+  obj = get_oom_object (inspector, "CommandBars");
   if (!obj)
     log_error ("%s:%s: CommandBars not found", SRCNAME, __func__);
   else
     {
-      button = get_oom_control_bytag (obj, "GpgOL_Inspector_Crypto_Info");
+      button = get_button (m_serialno, "GpgOL_Inspector_Crypto_Info");
       obj->Release ();
       if (button)
         {
@@ -453,40 +543,125 @@ is_inspector_in_composer_mode (LPDISPATCH inspector)
 }
 
 
-/* Add all the controls.  */
-void
-add_inspector_controls (LPOOMINSPECTOR inspector)
+/* Get the flags from the inspector; i.e. whether to sign or encrypt a
+   message.  Returns 0 on success.  */
+int
+get_inspector_composer_flags (LPDISPATCH inspector,
+                              bool *r_sign, bool *r_encrypt)
 {
-  LPDISPATCH obj, controls, button;
-  inspector_info_t inspinfo;
-  button_list_t buttonlist = NULL;
-  const char *tag;
-  int in_composer;
+  LPDISPATCH button;
+  int rc = 0;
+  unsigned long serialno;
 
-  log_debug ("%s:%s: Enter", SRCNAME, __func__);
+  serialno = get_serialno (inspector);
+  if (!serialno)
+    {
+      log_error ("%s:%s: S/n not found", SRCNAME, __func__);
+      return -1;
+    }
 
-  /* In theory we should take a lock here to avoid a race between the
-     test for a new control and the creation.  However, we are not
-     called from a second thread.  FIXME: We might want to use
-     inspector_info insteasd to check this.  However this requires us
-     to keep a lock per inspector. */
+  button = get_button (serialno, "GpgOL_Inspector_Sign");
+  if (!button)
+    {
+      log_error ("%s:%s: Sign button not found", SRCNAME, __func__);
+      rc = -1;
+    }
+  else
+    {
+      *r_sign = get_oom_int (button, "State") == msoButtonDown;
+      button->Release ();
+    }
 
-  /* Check that our controls do not already exist.  */
-  obj = get_oom_object (inspector, "CommandBars");
-  if (!obj)
+  button = get_button (serialno, "GpgOL_Inspector_Encrypt");
+  if (!button)
     {
-      log_error ("%s:%s: CommandBars not found", SRCNAME, __func__);
-      return;
+      log_error ("%s:%s: Encrypt button not found", SRCNAME, __func__);
+      rc = -1;
     }
-  button= get_oom_control_bytag (obj, "GpgOL_Inspector_Crypto_Info");
-  obj->Release ();
-  if (button)
+  else
     {
+      *r_encrypt = get_oom_int (button, "State") == msoButtonDown;
+      button->Release ();
+    }
+  
+  if (!rc)
+    log_debug ("%s:%s: sign=%d encrypt=%d",
+               SRCNAME, __func__, *r_sign, *r_encrypt);
+  return rc;
+}
+
+
+/* Set the flags for the inspector; i.e. whether to sign or encrypt a
+   message.  Returns 0 on success.  */
+int
+set_inspector_composer_flags (LPDISPATCH inspector, bool sign, bool encrypt)
+{
+  LPDISPATCH button;
+  int rc = 0;
+  unsigned long serialno;
+
+  serialno = get_serialno (inspector);
+  if (!serialno)
+    {
+      log_error ("%s:%s: S/n not found", SRCNAME, __func__);
+      return -1;
+    }
+
+  button = get_button (serialno, "GpgOL_Inspector_Sign");
+  if (!button)
+    {
+      log_error ("%s:%s: Sign button not found", SRCNAME, __func__);
+      rc = -1;
+    }
+  else
+    {
+      if (put_oom_int (button, "State", sign? msoButtonDown : msoButtonUp))
+        rc = -1;
+      button->Release ();
+    }
+
+  button = get_button (serialno, "GpgOL_Inspector_Encrypt");
+  if (!button)
+    {
+      log_error ("%s:%s: Encrypt button not found", SRCNAME, __func__);
+      rc = -1;
+    }
+  else
+    {
+      if (put_oom_int (button, "State", encrypt? msoButtonDown : msoButtonUp))
+        rc = -1;
       button->Release ();
-      log_debug ("%s:%s: Leave (Controls are already added)",
-                 SRCNAME, __func__);
-      return;
     }
+  
+  return rc;
+}
+
+
+/* Helper to make the tag unique.  */
+static const char *
+add_tag (LPDISPATCH control, unsigned long serialno, const char *value)
+{
+  char buf[256];
+  
+  snprintf (buf, sizeof buf, "%s#%lu", value, serialno);
+  put_oom_string (control, "Tag", buf);
+  return value;
+}
+
+
+/* Add all the controls.  */
+static void
+add_inspector_controls (LPOOMINSPECTOR inspector, unsigned long serialno)
+{
+  static
+  LPDISPATCH obj, controls, button;
+  inspector_info_t inspinfo;
+  button_list_t buttonlist = NULL;
+  const char *tag;
+  int in_composer;
+
+
+  log_debug ("%s:%s: Enter", SRCNAME, __func__);
 
   /* Check whether we are in composer or read mode.  */
   in_composer = is_inspector_in_composer_mode (inspector);
@@ -503,7 +678,7 @@ add_inspector_controls (LPOOMINSPECTOR inspector)
           button = opt.disable_gpgol? NULL : add_oom_button (controls);
           if (button)
             {
-              put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Encrypt"));
+              tag = add_tag (button, serialno, "GpgOL_Inspector_Encrypt");
               put_oom_bool (button, "BeginGroup", true);
               put_oom_int (button, "Style", msoButtonIconAndCaption );
               put_oom_string (button, "Caption",
@@ -511,19 +686,19 @@ add_inspector_controls (LPOOMINSPECTOR inspector)
               put_oom_icon (button, IDB_ENCRYPT, 16);
               
               obj = install_GpgolCommandBarButtonEvents_sink (button);
-              move_to_button_list (&buttonlist, obj, button, tag);
+              move_to_button_list (&buttonlist, obj, button, tag, serialno);
             }
           
           button = opt.disable_gpgol? NULL : add_oom_button (controls);
           if (button)
             {
-              put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Sign"));
+              tag = add_tag (button, serialno, "GpgOL_Inspector_Sign");
               put_oom_int (button, "Style", msoButtonIconAndCaption );
               put_oom_string (button, "Caption", _("&sign message with GnuPG"));
               put_oom_icon (button, IDB_SIGN, 16);
               
               obj = install_GpgolCommandBarButtonEvents_sink (button);
-              move_to_button_list (&buttonlist, obj, button, tag);
+              move_to_button_list (&buttonlist, obj, button, tag, serialno);
             }
           
           controls->Release ();
@@ -541,49 +716,49 @@ add_inspector_controls (LPOOMINSPECTOR inspector)
       button = in_composer? NULL : add_oom_button (controls);
       if (button)
         {
-          put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Verify"));
+          tag = add_tag (button, serialno, "GpgOL_Inspector_Verify");
           put_oom_int (button, "Style", msoButtonIconAndCaption );
           put_oom_string (button, "Caption", _("GpgOL Decrypt/Verify"));
           put_oom_icon (button, IDB_DECRYPT_VERIFY, 16);
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag);
+          move_to_button_list (&buttonlist, obj, button, tag, serialno);
         }
 
       button = opt.enable_debug? add_oom_button (controls) : NULL;
       if (button)
         {
-          put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Debug-0"));
+          tag = add_tag (button, serialno, "GpgOL_Inspector_Debug-0");
           put_oom_int (button, "Style", msoButtonCaption );
           put_oom_string (button, "Caption",
                           "GpgOL Debug-0 (display crypto info)");
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag);
+          move_to_button_list (&buttonlist, obj, button, tag, serialno);
         }
 
       button = opt.enable_debug? add_oom_button (controls) : NULL;
       if (button)
         {
-          put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Debug-1"));
+          tag = add_tag (button, serialno, "GpgOL_Inspector_Debug-1");
           put_oom_int (button, "Style", msoButtonCaption );
           put_oom_string (button, "Caption",
                           "GpgOL Debug-1 (open_inspector)");
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag);
+          move_to_button_list (&buttonlist, obj, button, tag, serialno);
         }
 
       button = opt.enable_debug? add_oom_button (controls) : NULL;
       if (button)
         {
-          put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Debug-2"));
+          tag = add_tag (button, serialno,"GpgOL_Inspector_Debug-2");
           put_oom_int (button, "Style", msoButtonCaption );
           put_oom_string (button, "Caption",
                           "GpgOL Debug-2 (change message class)");
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag);
+          move_to_button_list (&buttonlist, obj, button, tag, serialno);
         }
 
       controls->Release ();
@@ -602,38 +777,38 @@ add_inspector_controls (LPOOMINSPECTOR inspector)
                 ? NULL : add_oom_button (controls));
       if (button)
         {
-          put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Encrypt@t"));
+          tag = add_tag (button, serialno, "GpgOL_Inspector_Encrypt@t");
           put_oom_int (button, "Style", msoButtonIcon );
           put_oom_string (button, "Caption", _("Encrypt message with GnuPG"));
           put_oom_icon (button, IDB_ENCRYPT, 16);
           put_oom_int (button, "State", msoButtonMixed );
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag);
+          move_to_button_list (&buttonlist, obj, button, tag, serialno);
         }
 
       button = (opt.disable_gpgol || !in_composer
                 ? NULL : add_oom_button (controls));
       if (button)
         {
-          put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Sign@t"));
+          tag = add_tag (button, serialno, "GpgOL_Inspector_Sign@t");
           put_oom_int (button, "Style", msoButtonIcon);
           put_oom_string (button, "Caption", _("Sign message with GnuPG"));
           put_oom_icon (button, IDB_SIGN, 16);
           put_oom_int (button, "State", msoButtonDown);
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag);
+          move_to_button_list (&buttonlist, obj, button, tag, serialno);
         }
 
       button = in_composer? NULL : add_oom_button (controls);
       if (button)
         {
-          put_oom_string (button, "Tag", (tag = "GpgOL_Inspector_Crypto_Info"));
+          tag = add_tag (button, serialno, "GpgOL_Inspector_Crypto_Info");
           put_oom_int (button, "Style", msoButtonIcon);
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag);
+          move_to_button_list (&buttonlist, obj, button, tag, serialno);
         }
 
       controls->Release ();
@@ -763,14 +938,18 @@ toggle_button (LPDISPATCH button, const char *tag, int instid)
 {
   int state = get_oom_int (button, "State");
   char tag2[256];
+  char *p;
   LPDISPATCH button2;
 
-  log_debug ("%s:%s: button `%s' state is %d", SRCNAME, tag, __func__, state);
+  log_debug ("%s:%s: button `%s' state is %d", SRCNAME, __func__, tag, state);
   state = (state == msoButtonUp)? msoButtonDown : msoButtonUp;
   put_oom_int (button, "State", state);
 
   /* Toggle the other button.  */
   mem2str (tag2, tag, sizeof tag2 - 2);
+  p = strchr (tag2, '#');
+  if (p)
+    *p = 0;  /* Strip the serialno suffix.  */
   if (*tag2 && tag2[1] && !strcmp (tag2+strlen(tag2)-2, "@t"))
     tag2[strlen(tag2)-2] = 0; /* Remove the "@t".  */
   else
index 4bdf40c..31d0331 100644 (file)
@@ -37,6 +37,7 @@ typedef IOOMInspectorEvents *LPOOMINSPECTOREVENTS;
 typedef struct IOOMInspectorsEvents IOOMInspectorsEvents;
 typedef IOOMInspectorsEvents *LPOOMINSPECTORSEVENTS;
 
+
 EXTERN_C const IID IID_IOOMInspector;
 #undef INTERFACE
 #define INTERFACE  IOOMInspector
@@ -122,11 +123,14 @@ LPDISPATCH install_GpgolInspectorsEvents_sink (LPDISPATCH object);
 LPDISPATCH install_GpgolInspectorEvents_sink (LPDISPATCH object);
 
 
-void add_inspector_controls (LPOOMINSPECTOR inspector);
-
 void proc_inspector_button_click (LPDISPATCH button,
                                   const char *tag, int instid);
 
+int get_inspector_composer_flags (LPDISPATCH inspector,
+                                  bool *r_sign, bool *r_encrypt);
+int set_inspector_composer_flags (LPDISPATCH inspector,
+                                  bool sign, bool encrypt);
+
 
 
 
index ded7527..0b5b9df 100644 (file)
 
 #include "olflange-def.h"
 #include "olflange.h"
-#include "ol-ext-callback.h"
 #include "mimeparser.h"
 #include "mimemaker.h"
 #include "message.h"
 #include "message-events.h"
 
 #include "explorers.h"
+#include "inspectors.h"
 
 #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \
                                      SRCNAME, __func__, __LINE__); \
@@ -99,6 +99,47 @@ GpgolMessageEvents::QueryInterface (REFIID riid, LPVOID FAR *ppvObj)
 }
 
 
+/* Return the inspector the the current Mailitem.  If the inspector
+   does not exists, an inspector object is created (but not
+   immediatley shown).  */
+static LPDISPATCH
+get_inspector (LPEXCHEXTCALLBACK eecb)
+{
+  LPDISPATCH obj;
+  LPDISPATCH inspector = NULL;
+  
+  obj = get_eecb_object (eecb);
+  if (obj)
+    {
+      /* This should be MailItem; use the getInspector method.  */
+      inspector = get_oom_object (obj, "GetInspector");
+      obj->Release ();
+    }
+  return inspector;
+}
+
+
+static int
+get_crypto_flags (LPEXCHEXTCALLBACK eecb, bool *r_sign, bool *r_encrypt)
+{
+  LPDISPATCH inspector;
+  int rc;
+
+  inspector = get_inspector (eecb);
+  if (!inspector)
+    {
+      log_error ("%s:%s: inspector not found", SRCNAME, __func__);
+      rc = -1;
+    }
+  else
+    {
+      rc = get_inspector_composer_flags (inspector, r_sign, r_encrypt);
+      inspector->Release ();
+    }
+  return rc;
+}
+
+
 /* Called from Exchange on reading a message.  Returns: S_FALSE to
    signal Exchange to continue calling extensions.  EECB is a pointer
    to the IExchExtCallback interface. */
@@ -118,9 +159,6 @@ GpgolMessageEvents::OnRead (LPEXCHEXTCALLBACK eecb)
   log_debug ("%s:%s: received (hwnd=%p) %s\n", 
              SRCNAME, __func__, hwnd, m_gotinspector? "got_inspector":"");
 
-  show_event_object (eecb, __func__);
-  //add_oom_command_button (eecb);
-
   /* Fixme: If preview decryption is not enabled and we have an
      encrypted message, we might want to show a greyed out preview
      window.  There are two ways to clear the preview window: 
@@ -168,8 +206,6 @@ GpgolMessageEvents::OnReadComplete (LPEXCHEXTCALLBACK eecb, ULONG flags)
   log_debug ("%s:%s: received; flags=%#lx m_processed=%d \n",
              SRCNAME, __func__, flags, m_processed);
 
-  show_event_object (eecb, __func__);
-
   /* If the message has been processed by us (i.e. in OnRead), we now
      use our own display code.  */
   if (!flags && m_processed && !opt.disable_gpgol)
@@ -193,61 +229,37 @@ GpgolMessageEvents::OnReadComplete (LPEXCHEXTCALLBACK eecb, ULONG flags)
 STDMETHODIMP 
 GpgolMessageEvents::OnWrite (LPEXCHEXTCALLBACK eecb)
 {
-  log_debug ("%s:%s: received\n", SRCNAME, __func__);
-
-  HRESULT hr;
-  LPDISPATCH pDisp;
-  DISPID dispid;
-  VARIANT aVariant;
-  DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
+  LPDISPATCH obj;
   HWND hWnd = NULL;
+  bool sign, encrypt, need_crypto;
+  int bodyfmt;
 
+  log_debug ("%s:%s: received\n", SRCNAME, __func__);
+
+  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 ( (m_pExchExt->m_gpgEncrypt || m_pExchExt->m_gpgSign) 
-       && !opt.disable_gpgol)
+  if (need_crypto && !opt.disable_gpgol)
     {
-      pDisp = find_outlook_property (eecb, "BodyFormat", &dispid);
-      if (!pDisp)
-        {
-          log_debug ("%s:%s: BodyFormat not found\n", SRCNAME, __func__);
-          m_bWriteFailed = TRUE;       
-          return E_FAIL;
-        }
-      
-      aVariant.bstrVal = NULL;
-      hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                          DISPATCH_PROPERTYGET, &dispparamsNoArgs,
-                          &aVariant, NULL, NULL);
-      if (hr != S_OK)
-        {
-          log_debug ("%s:%s: retrieving BodyFormat failed: %#lx",
-                     SRCNAME, __func__, hr);
-          m_bWriteFailed = TRUE;       
-          pDisp->Release();
-          return E_FAIL;
-        }
-  
-      if (aVariant.vt != VT_INT && aVariant.vt != VT_I4)
+      obj = get_eecb_object (eecb);
+      if (!obj)
+        bodyfmt = -1;
+      else
         {
-          log_debug ("%s:%s: BodyFormat is not an integer (%d)",
-                     SRCNAME, __func__, aVariant.vt);
-          m_bWriteFailed = TRUE;       
-          pDisp->Release();
-          return E_FAIL;
+          bodyfmt = get_oom_int (obj, "BodyFormat");
+          obj->Release ();
         }
-  
-      if (aVariant.intVal == 1)
+
+      if (bodyfmt == 1)
         m_want_html = 0;
-      else if (aVariant.intVal == 2)
+      else if (bodyfmt == 2)
         m_want_html = 1;
       else
         {
-
-          log_debug ("%s:%s: BodyFormat is %d",
-                     SRCNAME, __func__, aVariant.intVal);
-          
+          log_debug ("%s:%s: BodyFormat is %d", SRCNAME, __func__, bodyfmt);
           if (FAILED(eecb->GetWindow (&hWnd)))
             hWnd = NULL;
           MessageBox (hWnd,
@@ -257,11 +269,8 @@ GpgolMessageEvents::OnWrite (LPEXCHEXTCALLBACK eecb)
                       "GpgOL", MB_ICONERROR|MB_OK);
 
           m_bWriteFailed = TRUE;       
-          pDisp->Release();
           return E_FAIL;
         }
-      pDisp->Release();
-      
     }
   
   
@@ -312,13 +321,17 @@ GpgolMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK eecb, ULONG flags)
   HRESULT hr = eecb->GetObject (&pMDB, (LPMAPIPROP *)&msg);
   if (SUCCEEDED (hr))
     {
-      protocol_t proto = m_pExchExt->m_protoSelection;
+      protocol_t proto = PROTOCOL_UNKNOWN; /* Let the UI server select
+                                              the protocol.  */
+      bool sign, encrypt;
 
-      if (m_pExchExt->m_gpgEncrypt && m_pExchExt->m_gpgSign)
+      if (get_crypto_flags (eecb, &sign, &encrypt))
+        rc = -1;
+      else if (encrypt && sign)
         rc = message_sign_encrypt (msg, proto, hWnd);
-      else if (m_pExchExt->m_gpgEncrypt && !m_pExchExt->m_gpgSign)
+      else if (encrypt && !sign)
         rc = message_encrypt (msg, proto, hWnd);
-      else if (!m_pExchExt->m_gpgEncrypt && m_pExchExt->m_gpgSign)
+      else if (!encrypt && sign)
         rc = message_sign (msg, proto, hWnd);
       else
         {
index 2fbf446..51d64fd 100644 (file)
@@ -30,7 +30,6 @@
 #include "mimeparser.h"
 #include "mimemaker.h"
 #include "display.h"
-#include "ol-ext-callback.h"
 #include "message.h"
 
 #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \
diff --git a/src/ol-ext-callback.cpp b/src/ol-ext-callback.cpp
deleted file mode 100644 (file)
index fa5d310..0000000
+++ /dev/null
@@ -1,619 +0,0 @@
-/* ol-ext-callback.cpp - Code to use the IOutlookExtCallback.
- *     Copyright (C) 2004, 2005, 2007 g10 Code 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/>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <windows.h>
-
-#include "mymapi.h"
-#include "mymapitags.h"
-#include "myexchext.h"
-#include "display.h"
-#include "common.h"
-#include "msgcache.h"
-#include "mapihelp.h"
-
-#include "olflange-def.h"
-#include "olflange.h"
-#include "ol-ext-callback.h"
-
-#define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \
-                                     SRCNAME, __func__, __LINE__); \
-                        } while (0)
-
-
-/* Wrapper around UlRelease with error checking. */
-static void 
-ul_release (LPVOID punk, const char *func, int lnr)
-{
-  ULONG res;
-  
-  if (!punk)
-    return;
-  res = UlRelease (punk);
-  if (opt.enable_debug & DBG_MEMORY)
-    log_debug ("%s:%s:%d: UlRelease(%p) had %lu references\n", 
-               SRCNAME, func, lnr, punk, res);
-}
-
-
-
-/* Locate a property using the provided callback LPEECB and traverse
-   down to the last element of the dot delimited NAME.  Returns the
-   Dispatch object and if R_DISPID is not NULL, the dispatch-id of the
-   last part.  Returns NULL on error.  The traversal implictly starts
-   at the object returned by the outlook application callback. */
-LPDISPATCH
-find_outlook_property (LPEXCHEXTCALLBACK lpeecb,
-                       const char *name, DISPID *r_dispid)
-{
-  HRESULT hr;
-  LPOUTLOOKEXTCALLBACK pCb;
-  LPUNKNOWN pObj;
-  LPDISPATCH pDisp;
-  DISPID dispid;
-  wchar_t *wname;
-  const char *s;
-
-  log_debug ("%s:%s: looking for `%s'\n", SRCNAME, __func__, name);
-
-  pCb = NULL;
-  pObj = NULL;
-  lpeecb->QueryInterface (IID_IOutlookExtCallback, (LPVOID*)&pCb);
-  if (pCb)
-    pCb->GetObject (&pObj);
-  for (; pObj && (s = strchr (name, '.')) && s != name; name = s + 1)
-    {
-      VARIANT vtResult;
-      char namepart[100];
-      size_t n;
-      char *p, *pend;
-      BSTR parmstr = NULL;
-
-      /* Our loop expects that all objects except for the last one are
-         of class IDispatch.  This is pretty reasonable. */
-      pObj->QueryInterface (IID_IDispatch, (LPVOID*)&pDisp);
-      if (!pDisp)
-        return NULL;
-
-      n = s - name;
-      if (n >= sizeof namepart)
-        n = sizeof namepart - 1;
-      strncpy (namepart, name, n);
-      namepart[n] = 0;
-
-      /* Parse a parameter (like "Print" in "Item(Print)").  */
-      p = strchr (namepart, '(');
-      if (p)
-        {
-          *p++ = 0;
-          pend = strchr (p, ')');
-          if (pend)
-            *pend = 0;
-          wname = utf8_to_wchar (p);
-          if (wname)
-            {
-              log_debug ("   parm(%s)=(%s)\n", namepart, p);
-              parmstr = SysAllocString (wname);
-              xfree (wname);
-            }
-        }
-
-      wname = utf8_to_wchar (namepart);
-      if (!wname)
-        {
-          if (parmstr)
-            SysFreeString (parmstr);
-          return NULL;
-        }
-
-      hr = pDisp->GetIDsOfNames(IID_NULL, &wname, 1,
-                                LOCALE_SYSTEM_DEFAULT, &dispid);
-      xfree (wname);
-      log_debug ("   dispid(%s)=%d  (hr=0x%x)\n",
-                 namepart, (int)dispid, (unsigned int)hr);
-
-      vtResult.pdispVal = NULL;
-      if (parmstr)
-        {
-          DISPPARAMS dispparams;
-          VARIANT aVariant[4];
-
-          dispparams.rgvarg = aVariant;
-          dispparams.rgvarg[0].vt = VT_BSTR;
-          dispparams.rgvarg[0].bstrVal = parmstr;
-          dispparams.cArgs = 1;
-          dispparams.cNamedArgs = 0;
-          hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                              DISPATCH_METHOD|DISPATCH_PROPERTYGET,
-                              &dispparams, &vtResult, NULL, NULL);
-          SysFreeString (parmstr);
-        }
-      else
-        {
-          DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
-
-          hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                              DISPATCH_METHOD, &dispparamsNoArgs,
-                              &vtResult, NULL, NULL);
-        }
-
-      pObj = vtResult.pdispVal;
-      /* FIXME: Check that the class of the returned object is as
-         expected.  To do this we better let GetIdsOfNames also return
-         the ID of "Class". */
-      log_debug ("   %s=%p vt=%d (hr=0x%x)\n",
-                 namepart, pObj, vtResult.vt, (unsigned int)hr);
-      pDisp->Release ();
-      pDisp = NULL;
-      if (vtResult.vt != VT_DISPATCH)
-        return NULL;
-      /* Fixme: Do we need to release pObj? */
-    }
-  if (!pObj || !*name)
-    return NULL;
-
-  pObj->QueryInterface (IID_IDispatch, (LPVOID*)&pDisp);
-  if (!pDisp)
-    return NULL;
-  wname = utf8_to_wchar (name);
-  if (!wname)
-    {
-      pDisp->Release ();
-      return NULL;
-    }
-      
-  hr = pDisp->GetIDsOfNames (IID_NULL, &wname, 1,
-                             LOCALE_SYSTEM_DEFAULT, &dispid);
-  xfree (wname);
-  log_debug ("   dispid(%s)=%d  (hr=0x%x)\n", name, (int)dispid, (int)hr);
-  if (r_dispid)
-    *r_dispid = dispid;
-
-  log_debug ("%s:%s:    got IDispatch=%p dispid=%u\n",
-            SRCNAME, __func__, pDisp, (unsigned int)dispid);
-  return pDisp;
-}
-
-
-int
-put_outlook_property (void *pEECB, const char *key, const char *value)
-{
-  int result = -1;
-  HRESULT hr;
-  LPMDB pMDB = NULL;
-  LPMESSAGE pMessage = NULL;
-  LPDISPATCH pDisp;
-  DISPID dispid;
-  DISPID dispid_put = DISPID_PROPERTYPUT;
-  DISPPARAMS dispparams;
-  VARIANT aVariant;
-  if (!pEECB)
-    return -1;
-
-  hr = ((LPEXCHEXTCALLBACK)pEECB)->GetObject (&pMDB, (LPMAPIPROP *)&pMessage);
-  if (FAILED (hr))
-    log_debug ("%s:%s: getObject failed: hr=%#lx\n", SRCNAME, __func__, hr);
-  else if ( (pDisp = find_outlook_property ((LPEXCHEXTCALLBACK)pEECB,
-                                            key, &dispid)))
-    {
-      BSTR abstr;
-
-      dispparams.cNamedArgs = 1;
-      dispparams.rgdispidNamedArgs = &dispid_put;
-      dispparams.cArgs = 1;
-      dispparams.rgvarg = &aVariant;
-      {
-        wchar_t *tmp = utf8_to_wchar (value);
-        abstr = SysAllocString (tmp);
-        xfree (tmp);
-      }
-      if (!abstr)
-        log_error ("%s:%s: SysAllocString failed\n", SRCNAME, __func__);
-      else
-        {
-          dispparams.rgvarg[0].vt = VT_BSTR;
-          dispparams.rgvarg[0].bstrVal = abstr;
-          hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                              DISPATCH_PROPERTYPUT, &dispparams,
-                              NULL, NULL, NULL);
-          log_debug ("%s:%s: PROPERTYPUT(%s) result -> %#lx\n",
-                     SRCNAME, __func__, key, hr);
-          SysFreeString (abstr);
-        }
-      
-      pDisp->Release ();
-      pDisp = NULL;
-      result = 0;
-    }
-
-  ul_release (pMessage, __func__, __LINE__);
-  ul_release (pMDB, __func__, __LINE__);
-  return result;
-}
-
-int
-put_outlook_property_int (void *pEECB, const char *key, int value)
-{
-  int result = -1;
-  HRESULT hr;
-  LPMDB pMDB = NULL;
-  LPMESSAGE pMessage = NULL;
-  LPDISPATCH pDisp;
-  DISPID dispid;
-  DISPID dispid_put = DISPID_PROPERTYPUT;
-  DISPPARAMS dispparams;
-  VARIANT aVariant;
-
-  if (!pEECB)
-    return -1;
-
-  hr = ((LPEXCHEXTCALLBACK)pEECB)->GetObject (&pMDB, (LPMAPIPROP *)&pMessage);
-  if (FAILED (hr))
-    log_debug ("%s:%s: getObject failed: hr=%#lx\n", SRCNAME, __func__, hr);
-  else if ( (pDisp = find_outlook_property ((LPEXCHEXTCALLBACK)pEECB,
-                                            key, &dispid)))
-    {
-      dispparams.cNamedArgs = 1;
-      dispparams.rgdispidNamedArgs = &dispid_put;
-      dispparams.cArgs = 1;
-      dispparams.rgvarg = &aVariant;
-      dispparams.rgvarg[0].vt = VT_I4;
-      dispparams.rgvarg[0].intVal = value;
-      hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                         DISPATCH_PROPERTYPUT, &dispparams,
-                         NULL, NULL, NULL);
-      log_debug ("%s:%s: PROPERTYPUT(%s) result -> %#lx\n",
-                 SRCNAME, __func__, key, hr);
-
-      pDisp->Release ();
-      pDisp = NULL;
-      result = 0;
-    }
-
-  ul_release (pMessage, __func__, __LINE__);
-  ul_release (pMDB, __func__, __LINE__);
-  return result;
-}
-
-
-/* Return an Outlook OO property named KEY.  This needs to be some
-   kind of string. PEECP is required to indificate the context.  On
-   error NULL is returned.   It is usually used with "Body". */
-char *
-get_outlook_property (void *pEECB, const char *key)
-{
-  char *result = NULL;
-  HRESULT hr;
-  LPDISPATCH pDisp;
-  DISPID dispid;
-  DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
-  VARIANT aVariant;
-
-  if (!pEECB)
-    return NULL;
-
-  pDisp = find_outlook_property ((LPEXCHEXTCALLBACK)pEECB, key, &dispid);
-  if (!pDisp)
-    return NULL;
-
-  aVariant.bstrVal = NULL;
-  hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                      DISPATCH_PROPERTYGET, &dispparamsNoArgs,
-                      &aVariant, NULL, NULL);
-  if (hr != S_OK)
-    log_debug ("%s:%s: retrieving `%s' failed: %#lx",
-               SRCNAME, __func__, key, hr);
-  else if (aVariant.vt != VT_BSTR)
-    log_debug ("%s:%s: `%s' is not a string (%d)",
-                           SRCNAME, __func__, key, aVariant.vt);
-  else if (aVariant.bstrVal)
-    {
-      result = wchar_to_utf8 (aVariant.bstrVal);
-      //log_debug ("%s:%s: `%s' is `%s'",
-      //           SRCNAME, __func__, key, result);
-      /* From MSDN (Invoke): It is up to the caller to free the return value.*/
-      SysFreeString (aVariant.bstrVal);
-    }
-
-  pDisp->Release();
-  pDisp = NULL;
-
-  return result;
-}
-
-
-/* Check whether the preview pane is visisble.  Returns:
-   -1 := Don't know.
-    0 := No
-    1 := Yes.
- */
-int
-is_preview_pane_visible (LPEXCHEXTCALLBACK eecb)
-{
-  HRESULT hr;      
-  LPDISPATCH pDisp;
-  DISPID dispid;
-  DISPPARAMS dispparams;
-  VARIANT aVariant, rVariant;
-      
-  pDisp = find_outlook_property (eecb,
-                                 "Application.ActiveExplorer.IsPaneVisible",
-                                 &dispid);
-  if (!pDisp)
-    {
-      log_debug ("%s:%s: ActiveExplorer.IsPaneVisible NOT found\n",
-                 SRCNAME, __func__);
-      return -1;
-    }
-
-  dispparams.rgvarg = &aVariant;
-  dispparams.rgvarg[0].vt = VT_INT;
-  dispparams.rgvarg[0].intVal = 3; /* olPreview */
-  dispparams.cArgs = 1;
-  dispparams.cNamedArgs = 0;
-  rVariant.bstrVal = NULL;
-  hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                      DISPATCH_METHOD, &dispparams,
-                      &rVariant, NULL, NULL);
-  pDisp->Release();
-  pDisp = NULL;
-  if (hr == S_OK && rVariant.vt != VT_BOOL)
-    {
-      log_debug ("%s:%s: invoking IsPaneVisible succeeded but vt is %d",
-                 SRCNAME, __func__, rVariant.vt);
-      if (rVariant.vt == VT_BSTR && rVariant.bstrVal)
-        SysFreeString (rVariant.bstrVal);
-      return -1;
-    }
-  if (hr != S_OK)
-    {
-      log_debug ("%s:%s: invoking IsPaneVisible failed: %#lx",
-                 SRCNAME, __func__, hr);
-      return -1;
-    }
-  
-  return !!rVariant.boolVal;
-  
-}
-
-
-/* Set the preview pane to visible if visble is true or to invisible
-   if visible is false.  */
-void
-show_preview_pane (LPEXCHEXTCALLBACK eecb, int visible)
-{
-  HRESULT hr;      
-  LPDISPATCH pDisp;
-  DISPID dispid;
-  DISPPARAMS dispparams;
-  VARIANT aVariant[2];
-      
-  pDisp = find_outlook_property (eecb,
-                                 "Application.ActiveExplorer.ShowPane",
-                                 &dispid);
-  if (!pDisp)
-    {
-      log_debug ("%s:%s: ActiveExplorer.ShowPane NOT found\n",
-                 SRCNAME, __func__);
-      return;
-    }
-
-  dispparams.rgvarg = aVariant;
-  dispparams.rgvarg[0].vt = VT_BOOL;
-  dispparams.rgvarg[0].boolVal = !!visible;
-  dispparams.rgvarg[1].vt = VT_INT;
-  dispparams.rgvarg[1].intVal = 3; /* olPreview */
-  dispparams.cArgs = 2;
-  dispparams.cNamedArgs = 0;
-  hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                      DISPATCH_METHOD, &dispparams,
-                      NULL, NULL, NULL);
-  pDisp->Release();
-  pDisp = NULL;
-  if (hr != S_OK)
-    log_debug ("%s:%s: invoking ShowPane(%d) failed: %#lx",
-               SRCNAME, __func__, visible, hr);
-}
-
-
-
-void
-show_event_object (LPEXCHEXTCALLBACK eecb, const char *description)
-{
-#if 1
-  (void)eecb;
-  (void)description;
-#else
-  HRESULT hr;
-  LPOUTLOOKEXTCALLBACK outlook_cb;
-  LPUNKNOWN obj;
-  LPDISPATCH disp;
-  LPTYPEINFO tinfo;
-  BSTR bstrname;
-  char *name;
-
-  log_debug ("%s:%s: looking for origin of event: %s\n", 
-             SRCNAME, __func__, description);
-
-  outlook_cb = NULL;
-  eecb->QueryInterface(IID_IOutlookExtCallback, (void **)&outlook_cb);
-  if (!outlook_cb)
-    {
-      log_debug ("%s%s: no outlook callback found\n", SRCNAME, __func__);
-      return;
-    }
-               
-  obj = NULL;
-  outlook_cb->GetObject (&obj);
-  if (!obj)
-    {
-      log_debug ("%s%s: no object found for event\n", SRCNAME, __func__);
-      outlook_cb->Release ();
-      return;
-    }
-
-  disp = NULL;
-  obj->QueryInterface (IID_IDispatch, (void **)&disp);
-  obj->Release ();
-  obj = NULL;
-  if (!disp)
-    {
-      log_debug ("%s%s: no dispatcher found for event\n", SRCNAME, __func__);
-      outlook_cb->Release ();
-      return;
-    }
-
-  tinfo = NULL;
-  disp->GetTypeInfo (0, 0, &tinfo);
-  if (!tinfo)
-    {
-      log_debug ("%s%s: no typeinfo found for dispatcher\n", 
-                 SRCNAME, __func__);
-      disp->Release ();
-      outlook_cb->Release ();
-      return;
-    }
-
-  bstrname = NULL;
-  hr = tinfo->GetDocumentation (MEMBERID_NIL, &bstrname, 0, 0, 0);
-  if (hr || !bstrname)
-    log_debug ("%s%s: GetDocumentation failed: hr=%#lx\n", 
-               SRCNAME, __func__, hr);
-
-  if (bstrname)
-    {
-      name = wchar_to_utf8 (bstrname);
-      SysFreeString (bstrname);
-      log_debug ("%s:%s: event fired by item type `%s'\n",
-                 SRCNAME, __func__, name);
-      xfree (name);
-    }
-
-  disp->Release ();
-  outlook_cb->Release ();
-#endif
-}
-
-\f
-/* 
-   Test code
- */
-void
-add_oom_command_button (LPEXCHEXTCALLBACK eecb)
-{
-  HRESULT hr;      
-  LPUNKNOWN pObj;
-  LPDISPATCH pDisp;
-  DISPID dispid;
-  DISPPARAMS dispparams;
-  VARIANT aVariant[5];
-  VARIANT rVariant;
-  const char name[] = 
-    "Application.ActiveExplorer.CommandBars.Item(Standard).FindControl";
-
-  log_debug ("%s:%s: ENTER", SRCNAME, __func__);
-  pDisp = find_outlook_property (eecb, name, &dispid);
-  if (!pDisp)
-    {
-      log_debug ("%s:%s: %s NOT found\n",
-                 SRCNAME, __func__, name);
-      return;
-    }
-
-  dispparams.rgvarg = aVariant;
-  dispparams.rgvarg[0].vt = VT_ERROR;
-  dispparams.rgvarg[0].scode = DISP_E_PARAMNOTFOUND; 
-  dispparams.rgvarg[1].vt = VT_ERROR;
-  dispparams.rgvarg[1].scode = DISP_E_PARAMNOTFOUND; 
-  dispparams.rgvarg[2].vt = VT_INT;
-  dispparams.rgvarg[2].intVal = 4; /* Print button.  */
-  dispparams.rgvarg[3].vt = VT_ERROR;
-  dispparams.rgvarg[3].scode = DISP_E_PARAMNOTFOUND; 
-  dispparams.cArgs = 4;
-  dispparams.cNamedArgs = 0;
-  rVariant.bstrVal = NULL;
-  hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                      DISPATCH_METHOD, &dispparams,
-                      &rVariant, NULL, NULL);
-  pDisp->Release();
-  pDisp = NULL;
-  if (hr != S_OK)
-    {
-      log_debug ("%s:%s: invoking %s failed: %#lx",
-                 SRCNAME, __func__, name, hr);
-      return ;
-    }
-
-  log_debug ("%s:%s: invoking %s succeeded; vt is %d",
-             SRCNAME, __func__, name, rVariant.vt);
-  if (rVariant.vt == VT_DISPATCH)
-    {
-      log_debug ("%s:%s:   rVariant.pdispVal=%p", 
-                 SRCNAME, __func__, rVariant.pdispVal);
-      pObj = rVariant.pdispVal;
-      pObj->QueryInterface (IID_IDispatch, (LPVOID*)&pDisp);
-      log_debug ("%s:%s:   queryinterface=%p", 
-                 SRCNAME, __func__, pDisp);
-      if (pDisp)
-        {
-          DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
-          VARIANT rVariant2;
-          char *result;
-          wchar_t *wname;
-
-          wname = utf8_to_wchar ("Caption");
-          if (!wname)
-            return;
-
-          hr = pDisp->GetIDsOfNames(IID_NULL, &wname, 1,
-                                    LOCALE_SYSTEM_DEFAULT, &dispid);
-          xfree (wname);
-          log_debug ("   dispid(%s)=%d  (hr=0x%x)\n",
-                        "Caption", (int)dispid, (unsigned int)hr);
-          
-          rVariant2.bstrVal = NULL;
-          hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                              DISPATCH_PROPERTYGET, &dispparamsNoArgs,
-                              &rVariant2, NULL, NULL);
-          if (hr != S_OK)
-            log_debug ("%s:%s: retrieving dispid failed: %#lx",
-                       SRCNAME, __func__, hr);
-          else if (rVariant2.vt != VT_BSTR)
-            log_debug ("%s:%s: id is not a string but vt %d",
-                           SRCNAME, __func__, rVariant2.vt);
-          else if (rVariant2.bstrVal)
-            {
-              result = wchar_to_utf8 (rVariant2.bstrVal);
-              log_debug ("%s:%s: `id is `%s'", SRCNAME, __func__,  result);
-              SysFreeString (rVariant2.bstrVal);
-              xfree (result);
-            }
-        }
-    }
-  else
-    log_debug ("%s:%s: ERROR: unexpected vt", SRCNAME, __func__);
-    
-  if (rVariant.vt == VT_BSTR && rVariant.bstrVal)
-    SysFreeString (rVariant.bstrVal);
-}
-
-
diff --git a/src/ol-ext-callback.h b/src/ol-ext-callback.h
deleted file mode 100644 (file)
index 7964df7..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ol-ext-callback.h - Definitions for ol-ext-callback.cpp
- *     Copyright (C) 2005, 2007 g10 Code 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 OL_EXT_CALLBACK_H
-#define OL_EXT_CALLBACK_H
-
-#include "myexchext.h"
-
-LPDISPATCH find_outlook_property (LPEXCHEXTCALLBACK lpeecb,
-                                  const char *name, DISPID *r_dispid);
-int put_outlook_property (void *pEECB, const char *key, const char *value);
-int put_outlook_property_int (void *pEECB, const char *key, int value);
-char *get_outlook_property (void *pEECB, const char *key);
-
-int is_preview_pane_visible (LPEXCHEXTCALLBACK eecb);
-void show_preview_pane (LPEXCHEXTCALLBACK eecb, int visible);
-
-void show_event_object (LPEXCHEXTCALLBACK eecb, const char *description);
-
-void add_oom_command_button (LPEXCHEXTCALLBACK eecb);
-
-
-#endif /*OL_EXT_CALLBACK_H*/
index b2bdae1..2e05aeb 100644 (file)
@@ -30,6 +30,9 @@ class GpgolItemEvents;
 
 bool GPGOptionsDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
+/* Retrieve the OOM object from the EECB.  */
+LPDISPATCH get_eecb_object (LPEXCHEXTCALLBACK eecb);
+
 
 #endif /*OLFLANGE_DEF_H*/
 
index c60c6a2..bbe7d72 100644 (file)
@@ -29,7 +29,6 @@
 #include "myexchext.h"
 #include "common.h"
 #include "display.h"
-#include "ol-ext-callback.h"
 #include "olflange-def.h"
 #include "dialogs.h"
 #include "engine.h"
index c35eba5..e6be7eb 100644 (file)
@@ -48,7 +48,6 @@
 #include "property-sheets.h"
 #include "attached-file-events.h"
 #include "item-events.h"
-#include "ol-ext-callback.h"
 #include "explorers.h"
 #include "inspectors.h"
 #include "cmdbarcontrols.h"
@@ -400,9 +399,6 @@ GpgolExt::GpgolExt (void)
   m_lRef = 1;
   m_lContext = 0;
   m_hWndExchange = 0;
-  m_protoSelection = PROTOCOL_UNKNOWN;
-  m_gpgEncrypt = FALSE;
-  m_gpgSign = FALSE;
 
   m_pExchExtCommands           = new GpgolExtCommands (this);
   m_pExchExtUserEvents         = new GpgolUserEvents (this);
@@ -603,7 +599,19 @@ GpgolExt::Install(LPEXCHEXTCALLBACK pEECB, ULONG lContext, ULONG lFlags)
      display the complete version and do a final test to see whether
      this is a supported version. */
   if (!olversion)
-    olversion = get_outlook_property (pEECB, "Application.Version");
+    {
+      LPDISPATCH obj = get_eecb_object (pEECB);
+      if (obj)
+        {
+          LPDISPATCH disp = get_oom_object (obj, "Application");
+          if (disp)
+            {
+              olversion = get_oom_string (disp, "Version");
+              disp->Release ();
+            }
+          obj->Release ();
+        }
+    }
   pEECB->GetVersion (&lBuildVersion, EECBGV_GETBUILDVERSION);
   pEECB->GetVersion (&lActualVersion, EECBGV_GETACTUALVERSION);
   pEECB->GetVersion (&lVirtualVersion, EECBGV_GETVIRTUALVERSION);
@@ -834,3 +842,34 @@ install_sinks (LPEXCHEXTCALLBACK eecb)
   
   log_debug ("%s:%s: Leave", SRCNAME, __func__);
 }
+
+
+/* Return the OOM object via EECB.  If it is not available return
+   NULL.  */
+LPDISPATCH
+get_eecb_object (LPEXCHEXTCALLBACK eecb)
+{
+  HRESULT hr;
+  LPOUTLOOKEXTCALLBACK pCb = NULL;
+  LPUNKNOWN pObj = NULL;
+  LPDISPATCH pDisp = NULL;
+  LPDISPATCH result = NULL;
+  
+  hr = eecb->QueryInterface (IID_IOutlookExtCallback, (LPVOID*)&pCb);
+  if (hr == S_OK && pCb)
+    {
+      pCb->GetObject (&pObj);
+      if (pObj)
+        {
+          /* We better query for IDispatch.  */
+          hr = pObj->QueryInterface (IID_IDispatch, (LPVOID*)&pDisp);
+          if (hr == S_OK && pDisp)
+            result = pDisp;
+          pObj->Release ();
+        }
+      pCb->Release ();
+    }
+  return result;
+}
+
+
index f6240b0..895cf7b 100644 (file)
@@ -38,11 +38,6 @@ public:
 public:        
   HWND m_hWndExchange;  /* Handle of the exchange window. */
 
-  /* Parameters for sending mails.  */
-  protocol_t  m_protoSelection;
-  BOOL  m_gpgEncrypt;
-  BOOL  m_gpgSign;
-  
 private:
   ULONG m_lRef;
   ULONG m_lContext;
index 1bde1d2..683ce6c 100644 (file)
@@ -119,7 +119,7 @@ get_oom_object (LPDISPATCH pStart, const char *fullname)
   LPDISPATCH pObj = pStart;
   LPDISPATCH pDisp = NULL;
 
-  log_debug ("%s:%s: looking for %p->`%s'\n",
+  log_debug ("%s:%s: looking for %p->`%s'",
              SRCNAME, __func__, pStart, fullname);
 
   while (pObj)
@@ -148,8 +148,11 @@ get_oom_object (LPDISPATCH pStart, const char *fullname)
       if (!pDisp)
         return NULL;  /* The object has no IDispatch interface.  */
       if (!*fullname)
-        return pDisp; /* Ready.  */
-
+        {
+          log_debug ("%s:%s:         got %p",SRCNAME, __func__, pDisp);
+          return pDisp; /* Ready.  */
+        }
+      
       /* Break out the next name part.  */
       {
         const char *dot;
@@ -257,11 +260,11 @@ get_oom_object (LPDISPATCH pStart, const char *fullname)
                           &vtResult, NULL, NULL);
       if (parmstr)
         SysFreeString (parmstr);
-      log_debug ("%s:%s:   %s=%p vt=%d (hr=0x%x)\n",
-                 SRCNAME, __func__,
-                 name, vtResult.pdispVal, vtResult.vt, (unsigned int)hr);
       if (hr != S_OK || vtResult.vt != VT_DISPATCH)
         {
+          log_debug ("%s:%s:       error: '%s' p=%p vt=%d hr=0x%x",
+                     SRCNAME, __func__,
+                     name, vtResult.pdispVal, vtResult.vt, (unsigned int)hr);
           VariantClear (&vtResult);
           if (parmstr)
             SysFreeString (parmstr);
@@ -271,7 +274,7 @@ get_oom_object (LPDISPATCH pStart, const char *fullname)
 
       pObj = vtResult.pdispVal;
     }
-
+  log_debug ("%s:%s:       error: no object", SRCNAME, __func__);
   return NULL;
 }
 
@@ -587,6 +590,7 @@ get_oom_control_bytag (LPDISPATCH pDisp, const char *tag)
   VARIANT aVariant[4];
   VARIANT rVariant;
   BSTR bstring;
+  LPDISPATCH result = NULL;
 
   dispid = lookup_oom_dispid (pDisp, "FindControl");
   if (dispid == DISPID_UNKNOWN)
@@ -622,13 +626,11 @@ get_oom_control_bytag (LPDISPATCH pDisp, const char *tag)
                       DISPATCH_METHOD, &dispparams,
                       &rVariant, NULL, NULL);
   SysFreeString (bstring);
-  pDisp->Release();
-  pDisp = NULL;
   if (hr == S_OK && rVariant.vt == VT_DISPATCH && rVariant.pdispVal)
     {
-      rVariant.pdispVal->QueryInterface (IID_IDispatch, (LPVOID*)&pDisp);
+      rVariant.pdispVal->QueryInterface (IID_IDispatch, (LPVOID*)&result);
       rVariant.pdispVal->Release ();
-      if (!pDisp)
+      if (!result)
         log_debug ("%s:%s: Object with tag `%s' has no dispatch intf.",
                    SRCNAME, __func__, tag);
     }
@@ -639,7 +641,7 @@ get_oom_control_bytag (LPDISPATCH pDisp, const char *tag)
       VariantClear (&rVariant);
     }
 
-  return pDisp;
+  return result;
 }
 
 
index cff402b..c56a9f5 100644 (file)
@@ -34,7 +34,6 @@
 
 #include "olflange-def.h"
 #include "olflange.h"
-#include "ol-ext-callback.h"
 #include "user-events.h"
 
 #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \