Add generic cache for IDispatch objects
[gpgol.git] / src / gpgoladdin.h
1 /* gpgoladdin.h - Connect GpgOL to Outlook as an addin
2  * Copyright (C) 2013 Intevation GmbH
3  *    2015 by Bundesamt für Sicherheit in der Informationstechnik
4  * Software engineering by Intevation GmbH
5  *
6  * This file is part of GpgOL.
7  *
8  * GpgOL is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * GpgOL is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #ifndef GPGOLADDIN_H
23 #define GPGOLADDIN_H
24
25 #include <windows.h>
26
27 #include "mymapi.h"
28
29 #include <vector>
30 #include <memory>
31
32 class GpgolAddinRibbonExt;
33 class ApplicationEventListener;
34 class DispCache;
35
36 /* Enums for the IDTExtensibility2 interface*/
37 typedef enum
38   {
39     ext_cm_AfterStartup = 0,
40     ext_cm_Startup,
41     ext_cm_External,
42     ext_cm_CommandLine,
43     ext_cm_Solution,
44     ext_cm_UISetup
45   }
46 ext_ConnectMode;
47
48 typedef enum
49   {
50     ext_dm_HostShutdown = 0,
51     ext_dm_UserClosed,
52     ext_dm_UISetupComplete,
53     ext_dm_SolutionClosed
54   }
55 ext_DisconnectMode;
56
57 /* Global class locks */
58 extern ULONG addinLocks;
59
60 struct IDTExtensibility2;
61 typedef struct IDTExtensibility2 *LEXTENSIBILTY2;
62
63 /* Interface definitions */
64 DEFINE_GUID(IID_IDTExtensibility2, 0xB65AD801, 0xABAF, 0x11D0, 0xBB, 0x8B,
65             0x00, 0xA0, 0xC9, 0x0F, 0x27, 0x44);
66
67 #undef INTERFACE
68 #define INTERFACE IDTExtensibility2
69 DECLARE_INTERFACE_(IDTExtensibility2, IDispatch)
70 {
71   DECLARE_IUNKNOWN_METHODS;
72   DECLARE_IDISPATCH_METHODS;
73   /*** IDTExtensibility2 methods ***/
74
75   STDMETHOD(OnConnection)(LPDISPATCH, ext_ConnectMode, LPDISPATCH,
76                           SAFEARRAY**) PURE;
77   STDMETHOD(OnDisconnection)(ext_DisconnectMode, SAFEARRAY**) PURE;
78   STDMETHOD(OnAddInsUpdate)(SAFEARRAY **) PURE;
79   STDMETHOD(OnStartupComplete)(SAFEARRAY**) PURE;
80   STDMETHOD(OnBeginShutdown)(SAFEARRAY**) PURE;
81 };
82
83 DEFINE_GUID(IID_IRibbonExtensibility, 0x000C0396, 0x0000, 0x0000, 0xC0, 0x00,
84             0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
85
86 struct IRibbonExtensibility;
87 typedef struct IRibbonExtensibility *LRIBBONEXTENSIBILITY;
88
89 #undef INTERFACE
90 #define INTERFACE IRibbonExtensibility
91 DECLARE_INTERFACE_(IRibbonExtensibility, IDispatch)
92 {
93   DECLARE_IUNKNOWN_METHODS;
94   DECLARE_IDISPATCH_METHODS;
95
96   /*** IRibbonExtensibility methods ***/
97   STDMETHOD(GetCustomUI)(BSTR RibbonID, BSTR * RibbonXml) PURE;
98 };
99
100 DEFINE_GUID(IID_IRibbonCallback, 0xCE895442, 0x9981, 0x4315, 0xAA, 0x85,
101             0x4B, 0x9A, 0x5C, 0x77, 0x39, 0xD8);
102
103 struct IRibbonCallback;
104 typedef struct IRibbonCallback *LRIBBONCALLBACK;
105
106 #undef INTERFACE
107 #define INTERFACE IRibbonCallback
108 DECLARE_INTERFACE_(IRibbonCallback, IUnknown)
109 {
110   DECLARE_IUNKNOWN_METHODS;
111
112   /*** IRibbonCallback methods ***/
113   STDMETHOD(OnRibbonLoad)(IUnknown* pRibbonUIUnk) PURE;
114   STDMETHOD(ButtonClicked)(IDispatch* ribbon) PURE;
115 };
116
117 DEFINE_GUID(IID_IRibbonControl, 0x000C0395, 0x0000, 0x0000, 0xC0, 0x00,
118             0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
119
120 struct IRibbonControl;
121 typedef struct IRibbonControl *LPRIBBONCONTROL;
122
123 #undef INTERFACE
124 #define INTERFACE IRibbonControl
125 DECLARE_INTERFACE_(IRibbonControl, IDispatch)
126 {
127   DECLARE_IUNKNOWN_METHODS;
128   DECLARE_IDISPATCH_METHODS;
129
130   STDMETHOD(get_Id)(BSTR* id) PURE;
131   STDMETHOD(get_Context)(IDispatch** context) PURE;
132   STDMETHOD(get_Tag)(BSTR* Tag) PURE;
133 };
134
135
136 DEFINE_GUID(IID_ICustomTaskPaneConsumer, 0x000C033E, 0x0000, 0x0000, 0xC0,
137             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46);
138
139 class GpgolRibbonExtender : public IRibbonExtensibility
140 {
141 public:
142   GpgolRibbonExtender(void);
143   virtual ~GpgolRibbonExtender();
144
145   /* IUnknown */
146   STDMETHODIMP QueryInterface (REFIID riid, LPVOID* ppvObj);
147   inline STDMETHODIMP_(ULONG) AddRef() { ++m_lRef;  return m_lRef; };
148   inline STDMETHODIMP_(ULONG) Release()
149     {
150       ULONG lCount = --m_lRef;
151       if (!lCount)
152         delete this;
153       return lCount;
154     };
155
156   /* IDispatch */
157   STDMETHODIMP GetTypeInfoCount (UINT*);
158   STDMETHODIMP GetTypeInfo (UINT, LCID, LPTYPEINFO*);
159   STDMETHODIMP GetIDsOfNames (REFIID, LPOLESTR*, UINT, LCID, DISPID*);
160   STDMETHODIMP Invoke (DISPID, REFIID, LCID, WORD,
161                        DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
162
163   /* IRibbonExtensibility */
164   STDMETHODIMP GetCustomUI (BSTR RibbonID, BSTR* RibbonXml);
165
166 private:
167   ULONG m_lRef;
168
169 };
170
171 class GpgolAddin : public IDTExtensibility2
172 {
173 public:
174   GpgolAddin(void);
175   virtual ~GpgolAddin();
176
177 public:
178
179   /* IUnknown */
180   STDMETHODIMP QueryInterface (REFIID riid, LPVOID* ppvObj);
181   inline STDMETHODIMP_(ULONG) AddRef() { ++m_lRef;  return m_lRef; };
182   inline STDMETHODIMP_(ULONG) Release()
183     {
184       ULONG lCount = --m_lRef;
185       if (!lCount)
186         delete this;
187       return lCount;
188     };
189
190   /* IDispatch */
191   STDMETHODIMP GetTypeInfoCount (UINT*);
192   STDMETHODIMP GetTypeInfo (UINT, LCID, LPTYPEINFO*);
193   STDMETHODIMP GetIDsOfNames (REFIID, LPOLESTR*, UINT, LCID, DISPID*);
194   STDMETHODIMP Invoke (DISPID, REFIID, LCID, WORD,
195                        DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
196
197   /* IDTExtensibility */
198   STDMETHODIMP OnConnection (LPDISPATCH Application,
199                              ext_ConnectMode ConnectMode,
200                              LPDISPATCH AddInInst,
201                              SAFEARRAY** custom);
202   STDMETHODIMP OnDisconnection (ext_DisconnectMode RemoveMode,
203                                 SAFEARRAY**  custom);
204   STDMETHODIMP OnAddInsUpdate (SAFEARRAY** custom);
205   STDMETHODIMP OnStartupComplete (SAFEARRAY** custom);
206   STDMETHODIMP OnBeginShutdown (SAFEARRAY** custom);
207
208 public:
209   static GpgolAddin * get_instance ();
210
211   void registerExplorerSink (LPDISPATCH sink);
212   void unregisterExplorerSink (LPDISPATCH sink);
213   /* Start the shutdown. Unregisters everything and closes all
214      crypto mails. */
215   void shutdown ();
216   LPDISPATCH get_application () { return m_application; }
217   std::shared_ptr<DispCache> get_dispcache () { return m_dispcache; }
218   bool isShutdown() { return m_shutdown; };
219
220 private:
221   ULONG m_lRef;
222   GpgolRibbonExtender* m_ribbonExtender;
223
224   LPDISPATCH m_application;
225   LPDISPATCH m_addin;
226   LPDISPATCH m_applicationEventSink;
227   LPDISPATCH m_explorersEventSink;
228   LPDISPATCH m_ribbon_control;
229   bool m_disabled;
230   bool m_shutdown;
231   HHOOK m_hook;
232   std::vector<LPDISPATCH> m_explorerEventSinks;
233   std::shared_ptr<DispCache> m_dispcache;
234 };
235
236 class GpgolAddinFactory: public IClassFactory
237 {
238 public:
239   GpgolAddinFactory(): m_lRef(0){}
240   virtual ~GpgolAddinFactory();
241
242   STDMETHODIMP QueryInterface (REFIID riid, LPVOID* ppvObj);
243   inline STDMETHODIMP_(ULONG) AddRef() { ++m_lRef;  return m_lRef; };
244   inline STDMETHODIMP_(ULONG) Release()
245     {
246       ULONG lCount = --m_lRef;
247       if (!lCount)
248         delete this;
249       return lCount;
250     };
251
252   /* IClassFactory */
253   STDMETHODIMP CreateInstance (LPUNKNOWN unknown, REFIID riid,
254                                LPVOID* ppvObj);
255   STDMETHODIMP LockServer (BOOL lock)
256     {
257       if (lock)
258         ++addinLocks;
259       else
260         --addinLocks;
261       return S_OK;
262     }
263
264 private:
265   ULONG m_lRef;
266 };
267
268 STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID* ppvObj);
269
270 /* Invalidates the UI XML to trigger a reload of the UI Elements. */
271 void gpgoladdin_invalidate_ui ();
272
273 #endif /*GPGOLADDIN_H*/