All fucked up ...
authorWerner Koch <wk@gnupg.org>
Tue, 23 Aug 2005 19:28:01 +0000 (19:28 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 23 Aug 2005 19:28:01 +0000 (19:28 +0000)
src/MapiGPGME.cpp
src/gpgmsg.cpp
src/msgcache.c
src/msgcache.h
src/olflange.cpp
src/util.h

index 1b04eb6..3921cfd 100644 (file)
@@ -263,11 +263,12 @@ public:
 
   bool __stdcall hasAttachments (void)
   {
-    if (attachRows == NULL)
-      getAttachments ();
-    bool has = attachRows->cRows > 0? true : false;
-    freeAttachments ();
-    return has;
+//     if (attachRows == NULL)
+//       getAttachments ();
+//     bool has = attachRows->cRows > 0? true : false;
+//     freeAttachments ();
+//    return has;
+    return false;    
   }
 
   bool __stdcall deleteAttachment (GpgMsg * msg, int pos)
@@ -429,7 +430,8 @@ unlock_log (void)
 
 
 static void
-do_log (const char *fmt, va_list a, int w32err)
+do_log (const char *fmt, va_list a, int w32err, int err,
+        const void *buf, size_t buflen)
 {
   if (enable_logging == false || !logfile)
     return;
@@ -446,6 +448,8 @@ do_log (const char *fmt, va_list a, int w32err)
   if (!logfp)
     return;
   fprintf (logfp, "%lu/", (unsigned long)GetCurrentThreadId ());
+  if (err == 1)
+    fputs ("ERROR/", logfp);
   vfprintf (logfp, fmt, a);
   if (w32err) 
     {
@@ -457,7 +461,15 @@ do_log (const char *fmt, va_list a, int w32err)
       fputs (": ", logfp);
       fputs (buf, logfp);
     }
-  if (*fmt && fmt[strlen (fmt) - 1] != '\n')
+  if (buf)
+    {
+      const unsigned char *p = (const unsigned char*)buf;
+
+      for ( ; buflen; buflen--, p++)
+        fprintf (logfp, "%02X", *p);
+      putc ('\n', logfp);
+    }
+  else if ( *fmt && fmt[strlen (fmt) - 1] != '\n')
     putc ('\n', logfp);
 
   fflush (logfp);
@@ -470,14 +482,24 @@ log_debug (const char *fmt, ...)
   va_list a;
   
   va_start (a, fmt);
-  do_log (fmt, a, 0);
+  do_log (fmt, a, 0, 0, NULL, 0);
+  va_end (a);
+}
+
+void 
+log_error (const char *fmt, ...)
+{
+  va_list a;
+  
+  va_start (a, fmt);
+  do_log (fmt, a, 0, 1, NULL, 0);
   va_end (a);
 }
 
 void 
 log_vdebug (const char *fmt, va_list a)
 {
-  do_log (fmt, a, 0);
+  do_log (fmt, a, 0, 0, NULL, 0);
 }
 
 
@@ -490,10 +512,36 @@ log_debug_w32 (int w32err, const char *fmt, ...)
       w32err = GetLastError ();
   
   va_start (a, fmt);
-  do_log (fmt, a, w32err);
+  do_log (fmt, a, w32err, 0, NULL, 0);
   va_end (a);
 }
 
+void 
+log_error_w32 (int w32err, const char *fmt, ...)
+{
+  va_list a;
+
+  if (w32err == -1)
+      w32err = GetLastError ();
+  
+  va_start (a, fmt);
+  do_log (fmt, a, w32err, 1, NULL, 0);
+  va_end (a);
+}
+
+
+void 
+log_hexdump (const void *buf, size_t buflen, const char *fmt, ...)
+{
+  va_list a;
+
+  va_start (a, fmt);
+  do_log (fmt, a, 0, 2, buf, buflen);
+  va_end (a);
+}
+
+
+
 
 
 
index f8a9d86..4454c69 100644 (file)
@@ -336,7 +336,8 @@ GpgMsgImpl::saveChanges (bool permanent)
   if (!body_plain)
     return; /* Nothing to save. */
 
-  return;
+  if (!permanent)
+    return;
   
   /* Make sure that the Plaintext and the Richtext are in sync. */
 //   if (message)
index ffb93cd..a2fea6c 100644 (file)
    so that the oldest messages are flushed from the cache first.  I
    don't think that it makes much sense to take the sieze of a message
    into account here.
+
+   FUBOH: This damned Outlook think is fucked up beyond all hacking.
+   After implementing this cace module here I realized that none of
+   the properties are taken from the message to the reply template:
+   Neither STORE_ENTRYID (which BTW is anyway constant within a
+   folder), nor ENTRYID, nor SEARCHID nor RECORD_KEY.  The only way to
+   solve this is by assuming that the last mail read will be the one
+   which gets replied to.  To implement this, we mark a message as the
+   active one through msgcache_set_active() called from the OnRead
+   hook.  msgcache_get will then simply return the active message.
 */
    
 
@@ -70,6 +80,12 @@ struct cache_item
   size_t length;    /* The length of that plaintext used to compute
                        the total size of the cache. */
 
+  int ref;          /* Reference counter, indicating how many callers
+                       are currently accessing the plaintext of this
+                       object. */
+
+  int is_active;    /* Flag, see comment at top. */
+
   /* The length of the key and the key itself.  The cache item is
      dynamically allocated to fit the size of the key.  Note, that
      the key is a binary blob. */
@@ -104,6 +120,28 @@ initialize_msgcache (void)
 }
 
 
+/* Acquire the mutex.  Returns 0 on success. */
+static int 
+lock_cache (void)
+{
+  int code = WaitForSingleObject (cache_mutex, INFINITE);
+  if (code != WAIT_OBJECT_0)
+    log_error ("%s:%s: waiting on mutex failed: code=%#x\n",
+               __FILE__, __func__, code);
+  return code != WAIT_OBJECT_0;
+}
+
+/* Release the mutex.  No error is returned because this is a fatal
+   error anyway and there is no way to clean up. */
+static void
+unlock_cache (void)
+{
+  if (!ReleaseMutex (cache_mutex))
+    log_error_w32 (-1, "%s:%s: ReleaseMutex failed", __FILE__, __func__);
+}
+
+
+
 /* Put the BODY of a message into the cache.  BODY should be a
    malloced string, UTF8 encoded.  If TRANSFER is given as true, the
    ownership of the malloced memory for BODY is transferred to this
@@ -112,28 +150,243 @@ initialize_msgcache (void)
 void
 msgcache_put (char *body, int transfer, LPMESSAGE message)
 {
+  HRESULT hr;
+  LPSPropValue lpspvFEID = NULL;
   cache_item_t item;
+  size_t keylen;
+  void *key;
+
+  if (!message)
+    return; /* No message: Nop. */
 
-  item = xcalloc (1, sizeof *item);
-  item->plaintext = xstrdup (body);
+  hr = HrGetOneProp ((LPMAPIPROP)message, PR_SEARCH_KEY, &lpspvFEID);
+  if (FAILED (hr))
+    {
+      log_error ("%s: HrGetOneProp failed: hr=%#lx\n", __func__, hr);
+      return;
+    }
+    
+  if ( PROP_TYPE (lpspvFEID->ulPropTag) != PT_BINARY )
+    {
+      log_error ("%s: HrGetOneProp returned unexpected property type\n",
+                 __func__);
+      MAPIFreeBuffer (lpspvFEID);
+      return;
+    }
+  keylen = lpspvFEID->Value.bin.cb;
+  key = lpspvFEID->Value.bin.lpb;
+
+  if (!keylen || !key || keylen > 10000)
+    {
+      log_error ("%s: malformed PR_SEARCH_KEY\n", __func__);
+      MAPIFreeBuffer (lpspvFEID);
+      return;
+    }
+
+  item = xmalloc (sizeof *item + keylen - 1);
+  item->next = NULL;
+  item->ref = 0;
+  item->is_active = 0;
+  item->plaintext = transfer? body : xstrdup (body);
   item->length = strlen (body);
+  item->keylen = keylen;
+  memcpy (item->key, key, keylen);
+
+  MAPIFreeBuffer (lpspvFEID);
 
-  the_cache = item;
+  if (!lock_cache ())
+    {
+      /* FIXME: Decide whether to kick out some entries. */
+      item->next = the_cache;
+      the_cache = item;
+      unlock_cache ();
+    }
+  msgcache_set_active (message);
+}
+
+
+/* If MESSAGE is in our cse set it's active flag and reset the active
+   flag of all others.  */
+void
+msgcache_set_active (LPMESSAGE message)
+{
+  HRESULT hr;
+  LPSPropValue lpspvFEID = NULL;
+  cache_item_t item;
+  size_t keylen = 0;
+  void *key = NULL;
+  int okay = 0;
+
+  if (!message)
+    return; /* No message: Nop. */
+  if (!the_cache)
+    return; /* No cache: avoid needless work. */
+  
+  hr = HrGetOneProp ((LPMAPIPROP)message, PR_SEARCH_KEY, &lpspvFEID);
+  if (FAILED (hr))
+    {
+      log_error ("%s: HrGetOneProp failed: hr=%#lx\n", __func__, hr);
+      goto leave;
+    }
+    
+  if ( PROP_TYPE (lpspvFEID->ulPropTag) != PT_BINARY )
+    {
+      log_error ("%s: HrGetOneProp returned unexpected property type\n",
+                 __func__);
+      goto leave;
+    }
+  keylen = lpspvFEID->Value.bin.cb;
+  key = lpspvFEID->Value.bin.lpb;
+
+  if (!keylen || !key || keylen > 10000)
+    {
+      log_error ("%s: malformed PR_SEARCH_KEY\n", __func__);
+      goto leave;
+    }
+  okay = 1;
+
+
+ leave:
+  if (!lock_cache ())
+    {
+      for (item = the_cache; item; item = item->next)
+        item->is_active = 0;
+      if (okay)
+        {
+          for (item = the_cache; item; item = item->next)
+            {
+              if (item->keylen == keylen 
+                  && !memcmp (item->key, key, keylen))
+                {
+                  item->is_active = 1;
+                  break;
+                }
+            }
+        }
+      unlock_cache ();
+    }
+
+  MAPIFreeBuffer (lpspvFEID);
 }
 
 
 /* Locate a plaintext stored under a key derived from the MAPI object
-   MESSAGE and return it.  Returns NULL if no plaintext is available.
-   FIXME: We need to make sure that the cache object is locked until
-   it has been processed by the caller - required a
-   msgcache_get_unlock fucntion or similar. */
+   MESSAGE and return it.  The user must provide the address of a void
+   pointer variable which he later needs to pass to the
+   msgcache_unref. Returns NULL if no plaintext is available;
+   msgcache_unref is then not required but won't harm either. */
 const char *
-msgcache_get (LPMESSAGE message)
+msgcache_get (LPMESSAGE message, void **refhandle)
 {
-  if (the_cache && the_cache->plaintext)
+  cache_item_t item;
+  const char *result = NULL;
+
+  *refhandle = NULL;
+
+  if (!message)
+    return NULL; /* No message: Nop. */
+  if (!the_cache)
+    return NULL; /* No cache: avoid needless work. */
+  
+#if 0 /* Old code, see comment at top of file. */
+  HRESULT hr;
+  LPSPropValue lpspvFEID = NULL;
+  size_t keylen;
+  void *key;
+
+  hr = HrGetOneProp ((LPMAPIPROP)message, PR_SEARCH_KEY, &lpspvFEID);
+  if (FAILED (hr))
+    {
+      log_error ("%s: HrGetOneProp failed: hr=%#lx\n", __func__, hr);
+      return NULL;
+    }
+    
+  if ( PROP_TYPE (lpspvFEID->ulPropTag) != PT_BINARY )
+    {
+      log_error ("%s: HrGetOneProp returned unexpected property type\n",
+                 __func__);
+      MAPIFreeBuffer (lpspvFEID);
+      return NULL;
+    }
+  keylen = lpspvFEID->Value.bin.cb;
+  key = lpspvFEID->Value.bin.lpb;
+
+  if (!keylen || !key || keylen > 10000)
     {
-      return the_cache->plaintext;
+      log_error ("%s: malformed PR_SEARCH_KEY\n", __func__);
+      MAPIFreeBuffer (lpspvFEID);
+      return NULL;
     }
-  return NULL;
+
+
+  if (!lock_cache ())
+    {
+      for (item = the_cache; item; item = item->next)
+        {
+          if (item->keylen == keylen 
+              && !memcmp (item->key, key, keylen))
+            {
+              item->ref++;
+              result = item->plaintext; 
+              *refhandle = item;
+              break;
+            }
+        }
+      unlock_cache ();
+    }
+
+  MAPIFreeBuffer (lpspvFEID);
+#else /* New code. */
+  if (!lock_cache ())
+    {
+      for (item = the_cache; item; item = item->next)
+        {
+          if (item->is_active)
+            {
+              item->ref++;
+              result = item->plaintext; 
+              *refhandle = item;
+              break;
+            }
+        }
+      unlock_cache ();
+    }
+
+#endif /* New code. */
+
+  return result;
 }
 
+
+/* Release access to a value returned by msgcache_get.  REFHANDLE is
+   the value as stored in the pointer variable by msgcache_get. */
+void
+msgcache_unref (void *refhandle)
+{
+  cache_item_t item;
+
+  if (!refhandle)
+    return;
+
+  if (!lock_cache ())
+    {
+      for (item = the_cache; item; item = item->next)
+        {
+          if (item == refhandle)
+            {
+              if (item->ref < 1)
+                log_error ("%s: zero reference count for item %p\n",
+                           __func__, item);
+              else
+                item->ref--;
+              /* Fixme: check whether this one has been scheduled for
+                 removal. */
+              break;
+            }
+        }
+      unlock_cache ();
+      if (!item)
+        log_error ("%s: invalid reference handle %p detected\n",
+                   __func__, refhandle);
+    }
+}
index 0b6f676..f5ee857 100644 (file)
@@ -35,9 +35,15 @@ int initialize_msgcache (void);
    controls whether the cache will snatch ownership of body. */
 void msgcache_put (char *body, int transfer, LPMESSAGE message);
 
+void msgcache_set_active (LPMESSAGE message);
+
 /* Return the plaintext stored under a key derived from MESSAGE or
    NULL if none was found. */
-const char *msgcache_get (LPMESSAGE message);
+const char *msgcache_get (LPMESSAGE message, void **refhandle);
+
+/* Release access to a value returned by msgcache_get.  REFHANDLE is
+   the value as stored in the pointer variable by msgcache_get. */
+void msgcache_unref (void *refhandle);
 
 
 #ifdef __cplusplus
index 9ee6460..bf281eb 100644 (file)
@@ -58,17 +58,6 @@ bool g_bInitDll = FALSE;
 MapiGPGME *m_gpg = NULL;
 
 
-static void 
-ExchLogInfo (const char * fmt, ...)
-{
-  va_list a;
-  
-  va_start (a, fmt);
-  log_vdebug (fmt, a);
-  va_end (a);
-}
-
-
 
 
 /* Registers this module as an Exchange extension. This basically updates
@@ -113,7 +102,7 @@ DllRegisterServer (void)
                                   REG_OPTION_NON_VOLATILE,
                                   KEY_ALL_ACCESS, NULL, &hkey, NULL);
     if (ec != ERROR_SUCCESS) {
-       ExchLogInfo ("DllRegisterServer failed\n");
+       log_debug ("DllRegisterServer failed\n");
        return E_ACCESSDENIED;
     }
     
@@ -137,7 +126,7 @@ DllRegisterServer (void)
     if (hkey != NULL)
        RegCloseKey (hkey);
 
-    ExchLogInfo ("DllRegisterServer succeeded\n");
+    log_debug ("DllRegisterServer succeeded\n");
     return S_OK;
 }
 
@@ -155,7 +144,7 @@ DllUnregisterServer (void)
                                    REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 
                                    NULL, &hkey, NULL);
     if (lResult != ERROR_SUCCESS) {
-       ExchLogInfo ("DllUnregisterServer: access denied.\n");
+       log_debug ("DllUnregisterServer: access denied.\n");
        return E_ACCESSDENIED;
     }
     RegDeleteValue (hkey, "OutlGPG");
@@ -170,6 +159,40 @@ DllUnregisterServer (void)
 }
 
 
+/* DISPLAY a MAPI property. */
+static void
+show_mapi_property (LPMESSAGE message, ULONG prop, const char *propname)
+{
+  HRESULT hr;
+  LPSPropValue lpspvFEID = NULL;
+  cache_item_t item;
+  size_t keylen;
+  void *key;
+
+  if (!message)
+    return; /* No message: Nop. */
+
+  hr = HrGetOneProp ((LPMAPIPROP)message, prop, &lpspvFEID);
+  if (FAILED (hr))
+    {
+      log_debug ("%s: HrGetOneProp(%s) failed: hr=%#lx\n",
+                 __func__, propname, hr);
+      return;
+    }
+    
+  if ( PROP_TYPE (lpspvFEID->ulPropTag) != PT_BINARY )
+    {
+      log_debug ("%s: HrGetOneProp(%s) returned unexpected property type\n",
+                 __func__, propname);
+      MAPIFreeBuffer (lpspvFEID);
+      return;
+    }
+  keylen = lpspvFEID->Value.bin.cb;
+  key = lpspvFEID->Value.bin.lpb;
+  log_hexdump (key, keylen, "%s: %20s=", __func__, propname);
+  MAPIFreeBuffer (lpspvFEID);
+}
+
 
 
 /* Locate a property using the current callback LPEECB and traverse
@@ -189,7 +212,7 @@ find_outlook_property (LPEXCHEXTCALLBACK lpeecb,
   wchar_t *wname;
   const char *s;
 
-  ExchLogInfo ("%s:%s: looking for `%s'\n", __FILE__, __func__, name);
+  log_debug ("%s:%s: looking for `%s'\n", __FILE__, __func__, name);
 
   pCb = NULL;
   pObj = NULL;
@@ -214,7 +237,7 @@ find_outlook_property (LPEXCHEXTCALLBACK lpeecb,
       hr = pDisp->GetIDsOfNames(IID_NULL, &wname, 1,
                                 LOCALE_SYSTEM_DEFAULT, &dispid);
       xfree (wname);
-      ExchLogInfo ("   dispid(%.*s)=%d  (hr=0x%x)\n",
+      log_debug ("   dispid(%.*s)=%d  (hr=0x%x)\n",
                    (int)(s-name), name, dispid, hr);
       vtResult.pdispVal = NULL;
       hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
@@ -224,7 +247,7 @@ find_outlook_property (LPEXCHEXTCALLBACK lpeecb,
       /* 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". */
-      ExchLogInfo ("%s:%s: %.*s=%p  (hr=0x%x)\n",
+      log_debug ("%s:%s: %.*s=%p  (hr=0x%x)\n",
                    __FILE__, __func__, (int)(s-name), name, pObj, hr);
       pDisp->Release ();
       pDisp = NULL;
@@ -246,11 +269,11 @@ find_outlook_property (LPEXCHEXTCALLBACK lpeecb,
   hr = pDisp->GetIDsOfNames(IID_NULL, &wname, 1,
                             LOCALE_SYSTEM_DEFAULT, &dispid);
   xfree (wname);
-  ExchLogInfo ("   dispid(%s)=%d  (hr=0x%x)\n", name, dispid, hr);
+  log_debug ("   dispid(%s)=%d  (hr=0x%x)\n", name, dispid, hr);
   if (r_dispid)
     *r_dispid = dispid;
 
-  ExchLogInfo ("%s:%s:    got IDispatch=%p dispid=%d\n",
+  log_debug ("%s:%s:    got IDispatch=%p dispid=%d\n",
                __FILE__, __func__, pDisp, dispid);
   return pDisp;
 }
@@ -289,7 +312,7 @@ get_outlook_application_object (LPEXCHEXTCALLBACK lpeecb)
       pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
                     DISPATCH_PROPERTYGET, &dispparamsNoArgs,
                     &vtResult, NULL, NULL);
-      ExchLogInfo ("%s:%s: Outlookcallback returned object of class=%d\n",
+      log_debug ("%s:%s: Outlookcallback returned object of class=%d\n",
                    __FILE__, __func__, vtResult.intVal);
     }
   if (pDisp)
@@ -300,13 +323,13 @@ get_outlook_application_object (LPEXCHEXTCALLBACK lpeecb)
       VARIANT vtResult;
       
       pDisp->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
-      //ExchLogInfo ("   dispid(Application)=%d\n", dispid);
+      //log_debug ("   dispid(Application)=%d\n", dispid);
       vtResult.pdispVal = NULL;
       pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
                      DISPATCH_METHOD, &dispparamsNoArgs,
                      &vtResult, NULL, NULL);
       pUnk = vtResult.pdispVal;
-      //ExchLogInfo ("%s:%s: Outlook.Application=%p\n",
+      //log_debug ("%s:%s: Outlook.Application=%p\n",
       //             __FILE__, __func__, pUnk);
       pDisp->Release();
       pDisp = NULL;
@@ -322,7 +345,7 @@ get_outlook_application_object (LPEXCHEXTCALLBACK lpeecb)
 EXTERN_C LPEXCHEXT __stdcall
 ExchEntryPoint (void)
 {
-  ExchLogInfo ("%s:%s: creating new CGPGExchExt object\n", __FILE__, __func__);
+  log_debug ("%s:%s: creating new CGPGExchExt object\n", __FILE__, __func__);
   return new CGPGExchExt;
 }
 
@@ -354,7 +377,7 @@ CGPGExchExt::CGPGExchExt (void)
           m_gpg->readOptions ();
         }
       g_bInitDll = TRUE;
-      ExchLogInfo ("%s:%s: one time init done\n", __FILE__, __func__);
+      log_debug ("%s:%s: one time init done\n", __FILE__, __func__);
     }
 }
 
@@ -364,7 +387,7 @@ CGPGExchExt::CGPGExchExt (void)
 */
 CGPGExchExt::~CGPGExchExt (void) 
 {
-  ExchLogInfo ("%s:%s: cleaning up CGPGExchExt object\n", __FILE__, __func__);
+  log_debug ("%s:%s: cleaning up CGPGExchExt object\n", __FILE__, __func__);
 
     if (m_lContext == EECONTEXT_SESSION) {
        if (g_bInitDll) {
@@ -374,7 +397,7 @@ CGPGExchExt::~CGPGExchExt (void)
                m_gpg = NULL;
            }
            g_bInitDll = FALSE;
-            ExchLogInfo ("%s:%s: one time deinit done\n", __FILE__, __func__);
+            log_debug ("%s:%s: one time deinit done\n", __FILE__, __func__);
        }       
     }
 }
@@ -416,7 +439,7 @@ CGPGExchExt::QueryInterface(REFIID riid, LPVOID *ppvObj)
     if (*ppvObj)
         ((LPUNKNOWN)*ppvObj)->AddRef();
 
-    /*ExchLogInfo("QueryInterface %d\n", __LINE__);*/
+    /*log_debug("QueryInterface %d\n", __LINE__);*/
     return hr;
 }
 
@@ -436,7 +459,7 @@ CGPGExchExt::Install(LPEXCHEXTCALLBACK pEECB, ULONG lContext, ULONG lFlags)
   /* Save the context in an instance variable. */
   m_lContext = lContext;
 
-  ExchLogInfo ("%s:%s: context=0x%lx (%s) flags=0x%lx\n", __FILE__, __func__, 
+  log_debug ("%s:%s: context=0x%lx (%s) flags=0x%lx\n", __FILE__, __func__, 
                lContext,
                (lContext == EECONTEXT_SESSION?           "Session":
                 lContext == EECONTEXT_VIEWER?            "Viewer":
@@ -459,7 +482,7 @@ CGPGExchExt::Install(LPEXCHEXTCALLBACK pEECB, ULONG lContext, ULONG lFlags)
   if (EECBGV_BUILDVERSION_MAJOR
       != (lBuildVersion & EECBGV_BUILDVERSION_MAJOR_MASK))
     {
-      ExchLogInfo ("%s:%s: invalid version 0x%lx\n",
+      log_debug ("%s:%s: invalid version 0x%lx\n",
                    __FILE__, __func__, lBuildVersion);
       return S_FALSE;
     }
@@ -475,13 +498,13 @@ CGPGExchExt::Install(LPEXCHEXTCALLBACK pEECB, ULONG lContext, ULONG lFlags)
       || lContext == EECONTEXT_READREPORTMESSAGE
       || lContext == EECONTEXT_VIEWER)
     {
-      LPUNKNOWN pApplication = get_outlook_application_object (pEECB);
-      ExchLogInfo ("%s:%s: pApplication=%p\n",
-                   __FILE__, __func__, pApplication);
+//       LPUNKNOWN pApplication = get_outlook_application_object (pEECB);
+//       log_debug ("%s:%s: pApplication=%p\n",
+//                    __FILE__, __func__, pApplication);
       return S_OK;
     }
   
-  ExchLogInfo ("%s:%s: can't handle this context\n", __FILE__, __func__);
+  log_debug ("%s:%s: can't handle this context\n", __FILE__, __func__);
   return S_FALSE;
 }
 
@@ -520,7 +543,19 @@ CGPGExchExtMessageEvents::QueryInterface (REFIID riid, LPVOID FAR *ppvObj)
 STDMETHODIMP 
 CGPGExchExtMessageEvents::OnRead (LPEXCHEXTCALLBACK pEECB) 
 {
-  ExchLogInfo ("%s:%s: received\n", __FILE__, __func__);
+  LPMDB pMDB = NULL;
+  LPMESSAGE pMessage = NULL;
+
+  log_debug ("%s:%s: received\n", __FILE__, __func__);
+
+  pEECB->GetObject (&pMDB, (LPMAPIPROP *)&pMessage);
+  show_mapi_property (pMessage, PR_ENTRYID, "ENTRYID");
+  show_mapi_property (pMessage, PR_SEARCH_KEY, "SEARCH_KEY");
+  msgcache_set_active (pMessage);
+  if (pMessage)
+    UlRelease(pMessage);
+  if (pMDB)
+    UlRelease(pMDB);
   return S_FALSE;
 }
 
@@ -532,7 +567,7 @@ STDMETHODIMP
 CGPGExchExtMessageEvents::OnReadComplete (LPEXCHEXTCALLBACK pEECB,
                                           ULONG lFlags)
 {
-    ExchLogInfo ("%s:%s: received\n", __FILE__, __func__);
+    log_debug ("%s:%s: received\n", __FILE__, __func__);
     return S_FALSE;
 }
 
@@ -543,7 +578,7 @@ CGPGExchExtMessageEvents::OnReadComplete (LPEXCHEXTCALLBACK pEECB,
 STDMETHODIMP 
 CGPGExchExtMessageEvents::OnWrite (LPEXCHEXTCALLBACK pEECB)
 {
-    ExchLogInfo ("%s:%s: received\n", __FILE__, __func__);
+    log_debug ("%s:%s: received\n", __FILE__, __func__);
     return S_FALSE;
 }
 
@@ -557,7 +592,7 @@ STDMETHODIMP
 CGPGExchExtMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK pEECB,
                                            ULONG lFlags)
 {
-  ExchLogInfo ("%s:%s: received\n", __FILE__, __func__);
+  log_debug ("%s:%s: received\n", __FILE__, __func__);
 
   HRESULT hrReturn = S_FALSE;
   LPMESSAGE msg = NULL;
@@ -613,7 +648,7 @@ CGPGExchExtMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK pEECB,
 STDMETHODIMP 
 CGPGExchExtMessageEvents::OnCheckNames(LPEXCHEXTCALLBACK pEECB)
 {
-  ExchLogInfo ("%s:%s: received\n", __FILE__, __func__);
+  log_debug ("%s:%s: received\n", __FILE__, __func__);
   return S_FALSE;
 }
 
@@ -625,7 +660,7 @@ STDMETHODIMP
 CGPGExchExtMessageEvents::OnCheckNamesComplete (LPEXCHEXTCALLBACK pEECB,
                                                 ULONG lFlags)
 {
-  ExchLogInfo ("%s:%s: received\n", __FILE__, __func__);
+  log_debug ("%s:%s: received\n", __FILE__, __func__);
   return S_FALSE;
 }
 
@@ -637,7 +672,7 @@ CGPGExchExtMessageEvents::OnCheckNamesComplete (LPEXCHEXTCALLBACK pEECB,
 STDMETHODIMP 
 CGPGExchExtMessageEvents::OnSubmit (LPEXCHEXTCALLBACK pEECB)
 {
-  ExchLogInfo ("%s:%s: received\n", __FILE__, __func__);
+  log_debug ("%s:%s: received\n", __FILE__, __func__);
   m_bOnSubmitActive = TRUE;
   m_bWriteFailed = FALSE;
   return S_FALSE;
@@ -650,7 +685,7 @@ STDMETHODIMP_ (VOID)
 CGPGExchExtMessageEvents::OnSubmitComplete (LPEXCHEXTCALLBACK pEECB,
                                             ULONG lFlags)
 {
-  ExchLogInfo ("%s:%s: received\n", __FILE__, __func__);
+  log_debug ("%s:%s: received\n", __FILE__, __func__);
   m_bOnSubmitActive = FALSE; 
 }
 
@@ -693,7 +728,7 @@ CGPGExchExtCommands::QueryInterface (REFIID riid, LPVOID FAR * ppvObj)
 //                     DISPATCH_PROPERTYGET, &dispparamsNoArgs,
 //                     &vtResult, NULL, NULL);
 
-//       ExchLogInfo ("%s:%s: Body=%p (%s)\n", __FILE__, __func__, 
+//       log_debug ("%s:%s: Body=%p (%s)\n", __FILE__, __func__, 
 //                    vtResult.pbVal,
 //                    (tmp = wchar_to_utf8 ((wchar_t*)vtResult.pbVal)));
 
@@ -725,7 +760,7 @@ CGPGExchExtCommands::InstallCommands (
   VARIANT aVariant;
   int force_encrypt = 0;
   
-  ExchLogInfo ("%s:%s: context=0x%lx (%s) flags=0x%lx\n", __FILE__, __func__, 
+  log_debug ("%s:%s: context=0x%lx (%s) flags=0x%lx\n", __FILE__, __func__, 
                m_lContext,
                (m_lContext == EECONTEXT_SESSION?           "Session"          :
                 m_lContext == EECONTEXT_VIEWER?            "Viewer"           :
@@ -744,6 +779,21 @@ CGPGExchExtCommands::InstallCommands (
                lFlags);
 
 
+  if (m_lContext == EECONTEXT_READNOTEMESSAGE
+      || m_lContext == EECONTEXT_SENDNOTEMESSAGE)
+    {
+      LPMDB pMDB = NULL;
+      LPMESSAGE pMessage = NULL;
+
+      pEECB->GetObject (&pMDB, (LPMAPIPROP *)&pMessage);
+      show_mapi_property (pMessage, PR_ENTRYID, "ENTRYID");
+      show_mapi_property (pMessage, PR_SEARCH_KEY, "SEARCH_KEY");
+      if (pMessage)
+        UlRelease(pMessage);
+      if (pMDB)
+        UlRelease(pMDB);
+    }
+
   /* Outlook 2003 sometimes displays the plaintext sometimes the
      orginal undecrypted text when doing a Reply.  This seems to
      depend on the sieze of the message; my guess it that only short
@@ -767,14 +817,15 @@ CGPGExchExtCommands::InstallCommands (
       LPMDB pMDB = NULL;
       LPMESSAGE pMessage = NULL;
       const char *body;
+      void *refhandle = NULL;
       
       /*  Note that for read and send the object returned by the
           outlook extension callback is of class 43 (MailItem) so we
           only need to ask for Body then. */
-        hr = pEECB->GetObject (&pMDB, (LPMAPIPROP *)&pMessage);
+      hr = pEECB->GetObject (&pMDB, (LPMAPIPROP *)&pMessage);
       if (FAILED(hr))
-        ExchLogInfo ("%s:%s: getObject failed: hr=%#x\n", hr);
-      else if ( (body = msgcache_get (pMessage)) 
+        log_debug ("%s:%s: getObject failed: hr=%#x\n", hr);
+      else if ( (body = msgcache_get (pMessage, &refhandle)) 
                 && (pDisp = find_outlook_property (pEECB, "Body", &dispid)))
         {
           dispparams.cNamedArgs = 1;
@@ -787,7 +838,7 @@ CGPGExchExtCommands::InstallCommands (
                              DISPATCH_PROPERTYPUT, &dispparams,
                              NULL, NULL, NULL);
           xfree (dispparams.rgvarg[0].bstrVal);
-          ExchLogInfo ("%s:%s: PROPERTYPUT(body) result -> %d\n",
+          log_debug ("%s:%s: PROPERTYPUT(body) result -> %d\n",
                        __FILE__, __func__, hr);
 
           pDisp->Release();
@@ -799,6 +850,11 @@ CGPGExchExtCommands::InstallCommands (
              gets encrypted too. */
           force_encrypt = 1;
         }
+      msgcache_unref (refhandle);
+      if (pMessage)
+        UlRelease(pMessage);
+      if (pMDB)
+        UlRelease(pMDB);
     }
 
 
@@ -952,6 +1008,8 @@ CGPGExchExtCommands::DoCommand (
       hr = pEECB->GetObject (&pMDB, (LPMAPIPROP *)&pMessage);
       if (SUCCEEDED (hr))
         {
+          show_mapi_property (pMessage, PR_ENTRYID, "ENTRYID");
+          show_mapi_property (pMessage, PR_SEARCH_KEY, "SEARCH_KEY");
           if (nCommandID == m_nCmdEncrypt)
             {
               GpgMsg *m = CreateGpgMsg (pMessage);
index 25d2a2b..53e22a7 100644 (file)
@@ -58,10 +58,14 @@ wchar_t *utf8_to_wchar2 (const char *string, size_t len);
 
 /*-- MapiGPGME.cpp --*/
 void log_debug (const char *fmt, ...) __attribute__ ((format (printf,1,2)));
+void log_error (const char *fmt, ...) __attribute__ ((format (printf,1,2)));
 void log_vdebug (const char *fmt, va_list a);
 void log_debug_w32 (int w32err, const char *fmt,
                     ...) __attribute__ ((format (printf,2,3)));
-
+void log_error_w32 (int w32err, const char *fmt,
+                    ...) __attribute__ ((format (printf,2,3)));
+void log_hexdump (const void *buf, size_t buflen, const char *fmt, ...)
+     __attribute__ ((format (printf,3,4)));
 
 /*****  Missing functions.  ****/