More missing files.. :-(
authorWerner Koch <wk@gnupg.org>
Tue, 3 Nov 2009 19:29:20 +0000 (19:29 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 3 Nov 2009 19:29:20 +0000 (19:29 +0000)
src/eventsink.h [new file with mode: 0644]

diff --git a/src/eventsink.h b/src/eventsink.h
new file mode 100644 (file)
index 0000000..634c483
--- /dev/null
@@ -0,0 +1,239 @@
+/* eventsink.h - Macros to implement an OLE event sink
+ *     Copyright (C) 2009 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/>.
+ */
+
+/* This is our lame implementation of event sinks.  It is sufficient
+   for our purpose but far from optimal; e.g. we should not simply
+   provide stubs but do real sub-classing by modifying the vtables.  */
+
+#ifndef EVENTSINK_H
+#define EVENTSINK_H
+
+#define debug_oom        (opt.enable_debug & DBG_OOM)
+
+
+#define BEGIN_EVENT_SINK(subcls,parentcls)                               \
+class subcls : public parentcls                                          \
+{                                                                        \
+ public:                                                                 \
+  subcls (void);                                                         \
+  ~subcls (void);                                                        \
+  LPDISPATCH m_object;                                                   \
+  LPCONNECTIONPOINT m_pCP;                                               \
+  DWORD m_cookie;                                                        \
+ private:                                                                \
+  ULONG     m_ref;                                                       \
+ public:                                                                 \
+  STDMETHODIMP QueryInterface (REFIID riid, LPVOID FAR *ppvObj);         \
+  inline STDMETHODIMP_(ULONG) AddRef (void)                              \
+    {                                                                    \
+      ++m_ref;                                                           \
+      if (debug_oom)                                                     \
+        log_debug ("%s:" #subcls ":%s: m_ref now %lu",                   \
+                   SRCNAME,__func__, m_ref);                             \
+      return m_ref;                                                      \
+    }                                                                    \
+  inline STDMETHODIMP_(ULONG) Release (void)                             \
+    {                                                                    \
+      ULONG count = --m_ref;                                             \
+      if (debug_oom)                                                     \
+        log_debug ("%s:" #subcls ":%s: mref now %lu",                    \
+                   SRCNAME,__func__,count);                              \
+      if (!count)                                                        \
+        delete this;                                                     \
+      return count;                                                      \
+    }                                                                    \
+  STDMETHODIMP GetTypeInfoCount (UINT*);                                 \
+  STDMETHODIMP GetTypeInfo (UINT, LCID, LPTYPEINFO*);                    \
+  STDMETHODIMP GetIDsOfNames (REFIID, LPOLESTR*, UINT, LCID, DISPID*);   \
+  STDMETHODIMP Invoke (DISPID, REFIID, LCID, WORD,                       \
+                       DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);        \
+/* End of macro BEGIN_EVENT_SINK.  */
+
+#define EVENT_SINK_CTOR(subcls)                                          \
+};                                                                       \
+subcls::subcls ()                                                        \
+{                                                                        \
+  m_ref = 1;                                                             \
+/* End of macro EVENT_SINK_CTOR.  */
+
+#define EVENT_SINK_DTOR(subcls)                                          \
+}                                                                        \
+subcls::~subcls ()                                                       \
+/* End of macro EVENT_SINK_DTOR.  */
+
+#define EVENT_SINK_INVOKE(subcls)                                        \
+STDMETHODIMP subcls::Invoke (DISPID dispid, REFIID riid, LCID lcid,      \
+                WORD flags, DISPPARAMS *parms, VARIANT *result,          \
+                EXCEPINFO *exepinfo, UINT *argerr)                       \
+/* End of macro EVENT_SINK_INVOKE.  */
+
+#define EVENT_SINK_DEFAULT_DTOR_CODE(subcls)                             \
+{                                                                        \
+  if (debug_oom)                                                         \
+    log_debug ("%s:" #subcls ":%s: tdor", SRCNAME, __func__);            \
+  if (m_pCP)                                                             \
+    log_error ("%s:%s: Unadvise missing", SRCNAME, __func__);            \
+  if (m_object)                                                          \
+    log_error ("%s:%s: Object not released", SRCNAME,__func__);          \
+}                                                                        \
+/* End of macro EVENT_SINK_DTOR_DEFAULT_CODE.  */
+
+
+#define EVENT_SINK_DEFAULT_CTOR(subcls)                                  \
+  EVENT_SINK_CTOR(subcls)                                                \
+/* End of macro EVENT_SINK_STD_DTOR.  */
+
+#define EVENT_SINK_DEFAULT_DTOR(subcls)                                  \
+  EVENT_SINK_DTOR(subcls)                                                \
+  EVENT_SINK_DEFAULT_DTOR_CODE(subcls)                                   \
+/* End of macro EVENT_SINK_STD_DTOR.  */
+
+
+#define END_EVENT_SINK(subcls,iidcls)                                    \
+STDMETHODIMP subcls::QueryInterface (REFIID riid, LPVOID FAR *ppvObj)    \
+{                                                                        \
+  /*log_debug ("%s:%s:%s: called riid=%08lx-%04hx-%04hx"                 \
+             "-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",                 \
+             SRCNAME, #subcls, __func__,                                 \
+             riid.Data1, riid.Data2, riid.Data3,                         \
+             riid.Data4[0], riid.Data4[1], riid.Data4[2],                \
+             riid.Data4[3], riid.Data4[4], riid.Data4[5],                \
+             riid.Data4[6], riid.Data4[7] );*/                           \
+  if (riid == IID_IUnknown || riid == iidcls || riid == IID_IDispatch)   \
+    {                                                                    \
+      *ppvObj = (LPUNKNOWN) this;                                        \
+      ((LPUNKNOWN)*ppvObj)->AddRef();                                    \
+      return S_OK;                                                       \
+    }                                                                    \
+  *ppvObj = NULL;                                                        \
+  return E_NOINTERFACE;                                                  \
+}                                                                        \
+STDMETHODIMP subcls::GetTypeInfoCount (UINT *r_count)                    \
+{                                                                        \
+  *r_count = 0;                                                          \
+  return S_OK;                                                           \
+}                                                                        \
+STDMETHODIMP subcls::GetTypeInfo (UINT iTypeInfo, LCID lcid,             \
+                                  LPTYPEINFO *r_typeinfo)                \
+{                                                                        \
+  (void)iTypeInfo;                                                       \
+  (void)lcid;                                                            \
+  (void)r_typeinfo;                                                      \
+  return E_NOINTERFACE;                                                  \
+}                                                                        \
+STDMETHODIMP subcls::GetIDsOfNames (REFIID riid, LPOLESTR *rgszNames,    \
+                                    UINT cNames, LCID lcid,              \
+                                    DISPID *rgDispId)                    \
+{                                                                        \
+  (void)riid;                                                            \
+  (void)rgszNames;                                                       \
+  (void)cNames;                                                          \
+  (void)lcid;                                                            \
+  (void)rgDispId;                                                        \
+  return E_NOINTERFACE;                                                  \
+}                                                                        \
+LPDISPATCH install_ ## subcls ## _sink (LPDISPATCH object)               \
+{                                                                        \
+  HRESULT hr;                                                            \
+  LPDISPATCH disp;                                                       \
+  LPCONNECTIONPOINTCONTAINER pCPC;                                       \
+  LPCONNECTIONPOINT pCP;                                                 \
+  subcls *sink;                                                          \
+  DWORD cookie;                                                          \
+                                                                         \
+  disp = NULL;                                                           \
+  hr = object->QueryInterface (IID_IConnectionPointContainer,            \
+                               (LPVOID*)&disp);                          \
+  if (hr != S_OK || !disp)                                               \
+    {                                                                    \
+      log_error ("%s:%s:%s: IConnectionPoint not supported: hr=%#lx",    \
+                 SRCNAME, #subcls, __func__, hr);                        \
+      return NULL;                                                       \
+    }                                                                    \
+  pCPC = (LPCONNECTIONPOINTCONTAINER)disp;                               \
+  pCP = NULL;                                                            \
+  hr = pCPC->FindConnectionPoint (iidcls, &pCP);                         \
+  if (hr != S_OK || !pCP)                                                \
+    {                                                                    \
+      log_error ("%s:%s:%s: ConnectionPoint not found: hr=%#lx",         \
+                 SRCNAME,#subcls,  __func__, hr);                        \
+      pCPC->Release ();                                                  \
+      return NULL;                                                       \
+    }                                                                    \
+  sink = new subcls; /* Note: Advise does another AddRef.  */            \
+  hr = pCP->Advise ((LPUNKNOWN)sink, &cookie);                           \
+  pCPC->Release ();                                                      \
+  if (hr != S_OK)                                                        \
+    {                                                                    \
+      log_error ("%s:%s:%s: Advice failed: hr=%#lx",                     \
+                 SRCNAME, #subcls, __func__, hr);                        \
+      pCP->Release ();                                                   \
+      sink->Release ();                                                  \
+      return NULL;                                                       \
+    }                                                                    \
+  if (debug_oom)                                                         \
+    log_debug ("%s:%s:%s: Advice succeeded", SRCNAME, #subcls, __func__);\
+  sink->m_cookie = cookie;                                               \
+  sink->m_pCP = pCP;                                                     \
+  object->AddRef ();                                                     \
+  sink->m_object = object;                                               \
+  return (LPDISPATCH)sink;                                               \
+}                                                                        \
+void detach_ ## subcls ## _sink (LPDISPATCH obj)                         \
+{                                                                        \
+  HRESULT hr;                                                            \
+  subcls *sink;                                                          \
+                                                                         \
+  if (debug_oom)                                                         \
+    log_debug ("%s:%s:%s: Called", SRCNAME, #subcls, __func__);          \
+  hr = obj->QueryInterface (iidcls, (void**)&sink);                      \
+  if (hr != S_OK || !sink)                                               \
+    {                                                                    \
+      log_error ("%s:%s:%s: invalid object passed: hr=%#lx",             \
+                 SRCNAME, #subcls, __func__, hr);                        \
+      return;                                                            \
+    }                                                                    \
+  if (sink->m_pCP)                                                       \
+    {                                                                    \
+      if (debug_oom)                                                     \
+        log_debug ("%s:%s:%s: Unadvising", SRCNAME, #subcls, __func__);  \
+      hr = sink->m_pCP->Unadvise (sink->m_cookie);                       \
+      if (hr != S_OK)                                                    \
+        log_error ("%s:%s:%s: Unadvice failed: hr=%#lx",                 \
+                   SRCNAME, #subcls, __func__, hr);                      \
+      if (debug_oom)                                                     \
+        log_debug ("%s:%s:%s: Releasing connt point",                    \
+                   SRCNAME, #subcls, __func__);                          \
+      sink->m_pCP->Release ();                                           \
+      sink->m_pCP = NULL;                                                \
+    }                                                                    \
+  if (sink->m_object)                                                    \
+    {                                                                    \
+      if (debug_oom)                                                     \
+        log_debug ("%s:%s:%s: Releasing actual object",                  \
+                   SRCNAME, #subcls, __func__);                          \
+      sink->m_object->Release ();                                        \
+      sink->m_object = NULL;                                             \
+    }                                                                    \
+  sink->Release ();                                                      \
+}                                                                        \
+/* End of macro END_EVENT_SINK.  */
+
+
+#endif /*EVENTSINK_H*/