1 /***
2 * comdef.h - Native C++ compiler COM support - main definitions header
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 ****/
7
8 #if _MSC_VER > 1000
9 #pragma once
10 #endif
11
12 #if !defined(_INC_COMDEF)
13 #define _INC_COMDEF
14 #if !defined(RC_INVOKED)
15
16 #ifndef  __cplusplus
17 #error Native Compiler support only available in C++ compiler
18 #endif
19
20 #ifdef _M_CEE_PURE
21 #error comdef.h header cannot be included under /clr:safe or /clr:pure
22 #endif
23
24 #include <ole2.h>
25 #include <olectl.h>
26
27 #include <comutil.h>
28
29 #pragma warning(push)
30 #pragma warning(disable: 4244)
31 #pragma warning(disable: 4290)
32
33 #ifdef _NATIVE_WCHAR_T_DEFINED
34 # ifdef _DEBUG
35 # pragma comment(lib, "comsuppwd.lib")
36 # else
37 # pragma comment(lib, "comsuppw.lib")
38 # endif
39 #else
40 # ifdef _DEBUG
41 # pragma comment(lib, "comsuppd.lib")
42 # else
43 # pragma comment(lib, "comsupp.lib")
44 # endif
45 #endif
46
47 #pragma comment(lib, "user32.lib")
48 #pragma comment(lib, "ole32.lib")
49 #pragma comment(lib, "oleaut32.lib")
50
51 class _com_error;
52
53 void __declspec(noreturn) __stdcall
54       _com_raise_error(HRESULT hr, IErrorInfo* perrinfo = 0) ;
55
56 void __stdcall 
57       _set_com_error_handler(void (__stdcall *pHandler)(HRESULT hr, IErrorInfo* perrinfo));
58
59 void __stdcall
60       _com_issue_error(HRESULT) ;
61 void __stdcall
62       _com_issue_errorex(HRESULT, IUnknown*, REFIID) ;
63
64 HRESULT __stdcall
65       _com_dispatch_propget(IDispatch*, DISPID, VARTYPE, void*) ;
66 HRESULT __cdecl
67       _com_dispatch_propput(IDispatch*, DISPID, VARTYPE, ...) ;
68 HRESULT __cdecl
69       _com_dispatch_method(IDispatch*, DISPID, WORD, VARTYPE, void*,
70                                          const wchar_t*, ...) ;
71
72 HRESULT __stdcall
73       _com_dispatch_raw_propget(IDispatch*, DISPID, VARTYPE, void*) throw();
74 HRESULT __cdecl
75       _com_dispatch_raw_propput(IDispatch*, DISPID, VARTYPE, ...) throw();
76 HRESULT __cdecl
77       _com_dispatch_raw_method(IDispatch*, DISPID, WORD, VARTYPE, void*,
78                                                 const wchar_t*, ...) throw();
79
80 class _com_error {
81 public:
82       // Constructors
83       //
84       _com_error(HRESULT hr,
85                          IErrorInfo* perrinfo = NULL,
86                          bool fAddRef = false) throw();
87       _com_error(const _com_error& that) throw();
88
89       // Destructor
90       //
91       virtual ~_com_error() throw();
92
93       // Assignment operator
94       //
95       _com_error& operator=(const _com_error& that) throw();
96
97       // Accessors
98       //
99       HRESULT Error() const throw();
100       WORD WCode() const throw();
101       IErrorInfo * ErrorInfo() const throw();
102
103       // IErrorInfo method accessors
104       //
105       _bstr_t Description() const ;
106       DWORD HelpContext() const throw();
107       _bstr_t HelpFile() const ;
108       _bstr_t Source() const ;
109       GUID GUID() const throw();
110
111       // FormatMessage accessors
112       //
113       const TCHAR * ErrorMessage() const throw();
114
115       // EXCEPINFO.wCode <-> HRESULT mappers
116       //
117       static HRESULT WCodeToHRESULT(WORD wCode) throw();
118       static WORD HRESULTToWCode(HRESULT hr) throw();
119
120 private:
121       enum {
122              WCODE_HRESULT_FIRST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x200),
123              WCODE_HRESULT_LAST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF+1, 0) - 1
124       };
125       const HRESULT                  m_hresult;
126       IErrorInfo *                    m_perrinfo;
127       mutable TCHAR *               m_pszMsg;
128 };
129
130 inline _com_error::_com_error(HRESULT hr,
131                                                   IErrorInfo* perrinfo,
132                                                   bool fAddRef) throw()
133       : m_hresult(hr), m_perrinfo(perrinfo), m_pszMsg(NULL)
134 {
135       if (m_perrinfo != NULL && fAddRef) {
136              m_perrinfo->AddRef();
137       }
138 }
139
140 inline _com_error::_com_error(const _com_error& that) throw()
141       : m_hresult(that.m_hresult), m_perrinfo(that.m_perrinfo), m_pszMsg(NULL)
142 {
143       if (m_perrinfo != NULL) {
144              m_perrinfo->AddRef();
145       }
146 }
147
148 inline _com_error::~_com_error() throw()
149 {
150       if (m_perrinfo != NULL) {
151              m_perrinfo->Release();
152       }
153       if (m_pszMsg != NULL) {
154              LocalFree((HLOCAL)m_pszMsg);
155       }
156 }
157
Lines 158 ... 167 are skipped.
168 {
169       return m_hresult;
170 }
171
172 inline WORD _com_error::WCode() const throw()
173 {
174       return HRESULTToWCode(m_hresult);
175 }
176
177 inline IErrorInfo * _com_error::ErrorInfo() const throw()
178 {
179       if (m_perrinfo != NULL) {
180              m_perrinfo->AddRef();
181       }
182       return m_perrinfo;
183 }
184
185 inline _bstr_t _com_error::Description() const 
186 {
187       BSTR bstr = NULL;
188       if (m_perrinfo != NULL) {
189              m_perrinfo->GetDescription(&bstr);
190       }
191       return _bstr_t(bstr, false);
192 }
193
194 inline DWORD _com_error::HelpContext() const throw()
195 {
196       DWORD dwHelpContext = 0;
197       if (m_perrinfo != NULL) {
198              m_perrinfo->GetHelpContext(&dwHelpContext);
199       }
200       return dwHelpContext;
201 }
202
203 inline _bstr_t _com_error::HelpFile() const 
204 {
205       BSTR bstr = NULL;
206       if (m_perrinfo != NULL) {
207              m_perrinfo->GetHelpFile(&bstr);
208       }
209       return _bstr_t(bstr, false);
210 }
211
212 inline _bstr_t _com_error::Source() const 
213 {
214       BSTR bstr = NULL;
215       if (m_perrinfo != NULL) {
216              m_perrinfo->GetSource(&bstr);
217       }
218       return _bstr_t(bstr, false);
219 }
220
221 inline _GUID _com_error::GUID() const throw()
222 {
223       _GUID guid;
224       _COM_MEMCPY_S(&guid, sizeof(_GUID), &__uuidof(NULL), sizeof(_GUID));
225       if (m_perrinfo != NULL) {
226              m_perrinfo->GetGUID(&guid);
227       } 
228       return guid;
229 }
230
231 inline const TCHAR * _com_error::ErrorMessage() const throw()
232 {
233       if (m_pszMsg == NULL) {
234              FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
235                                            FORMAT_MESSAGE_FROM_SYSTEM|
236                                            FORMAT_MESSAGE_IGNORE_INSERTS,
237                                     NULL,
238                                     m_hresult,
239                                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
240                                     (LPTSTR)&m_pszMsg,
241                                     0,
242                                     NULL);
243              if (m_pszMsg != NULL) {
244                     int nLen = lstrlen(m_pszMsg);
245                     if (nLen > 1 && m_pszMsg[nLen - 1] == '\n') {
246                           m_pszMsg[nLen - 1] = 0;
247                           if (m_pszMsg[nLen - 2] == '\r') {
248                                         m_pszMsg[nLen - 2] = 0;
249                           }
250                     }
251              } 
252              else {
253                     m_pszMsg = (LPTSTR)LocalAlloc(0, 32 * sizeof(TCHAR));
254                     if (m_pszMsg != NULL) {
255                           WORD wCode = WCode();
256                           if (wCode != 0) {
257                                  _COM_PRINTF_S_1(m_pszMsg, 32, TEXT("IDispatch error #%d"), wCode);
258                           } 
259                           else {
260                                  _COM_PRINTF_S_1(m_pszMsg, 32, TEXT("Unknown error 0x%0lX"), m_hresult);
261                           }
262                     }
263              }
264       }
265       return m_pszMsg;
266 }
267
268 inline HRESULT _com_error::WCodeToHRESULT(WORD wCode) throw()
269 {
270       return wCode >= 0xFE00 ? WCODE_HRESULT_LAST : WCODE_HRESULT_FIRST + wCode;
271 }
272
273 inline WORD _com_error::HRESULTToWCode(HRESULT hr) throw()
274 {
275       return (hr >= WCODE_HRESULT_FIRST && hr <= WCODE_HRESULT_LAST)
276              ? WORD(hr - WCODE_HRESULT_FIRST)
277              : 0;
278 }
279
280 //
281 // give missing types from dependent type libraries a chance
282 //
283 typedef int __missing_type__;
284
285 #if !defined(_COM_SMARTPTR)
286  #if !defined(_INC_COMIP)
287   #include <comip.h>
288  #endif
289  #define _COM_SMARTPTR             _com_ptr_t
290  #define _COM_SMARTPTR_LEVEL2 _com_IIID
291 #endif
292 #if defined(_COM_SMARTPTR)
293  #if !defined(_COM_SMARTPTR_TYPEDEF)
294   #if defined(_COM_SMARTPTR_LEVEL2)
295      #define _COM_SMARTPTR_TYPEDEF(Interface, IID) \
296       typedef _COM_SMARTPTR<_COM_SMARTPTR_LEVEL2<Interface, &IID> > \
297                     Interface ## Ptr
298   #else
299      #define _COM_SMARTPTR_TYPEDEF(Interface, IID) \
300       typedef _COM_SMARTPTR<Interface, &IID> \
301                     Interface ## Ptr
302   #endif
303  #endif
304 #endif
305
306 #if !defined(_COM_NO_STANDARD_GUIDS_)
307
308 // hard-coded smart pointer defs
309 #if defined(__IFontDisp_INTERFACE_DEFINED__)
310 __if_not_exists(Font)
311 {
312       struct Font : IFontDisp {};
313 }
314 _COM_SMARTPTR_TYPEDEF(Font, __uuidof(IDispatch));
315 #endif
316 #if defined(__IFontEventsDisp_INTERFACE_DEFINED__)
317 __if_not_exists(FontEvents)
318 {
319       struct FontEvents : IFontEventsDisp {};
320 }
321 _COM_SMARTPTR_TYPEDEF(FontEvents, __uuidof(IDispatch));
322 #endif
323 #if defined(__IPictureDisp_INTERFACE_DEFINED__)
324 __if_not_exists(Picture)
325 {
326       struct Picture : IPictureDisp {};
327 }
328 _COM_SMARTPTR_TYPEDEF(Picture, __uuidof(IDispatch));
329 #endif
330
331 #include "comdefsp.h"
332
333 #endif  /* _COM_NO_STANDARD_GUIDS_ */
334
335 #pragma warning(pop)
336
337 #endif /* RC_INVOKED */
338 #endif  /* _INC_COMDEF */
339
340
341