STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
comdef.h
Go to the documentation of this file.
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 #ifdef WINAPI_FAMILY
25 #include <winapifamily.h>
26 #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
27 #define _COMDEF_NOT_WINAPI_FAMILY_DESKTOP_APP
28 #endif /* !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
29 #if defined WINAPI_FAMILY_PHONE_APP && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
30 #define _COMDEF_WINAPI_FAMILY_PHONE_APP
31 #endif /* defined WINAPI_FAMILY_PHONE_APP && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) */
32 #endif /* WINAPI_FAMILY */
33 
34 #ifndef _COMDEF_WINAPI_FAMILY_PHONE_APP
35 #include <ole2.h>
36 
37 #include <comutil.h>
38 #endif /* _COMDEF_WINAPI_FAMILY_PHONE_APP */
39 
40 #pragma warning(push)
41 #pragma warning(disable: 4244)
42 #pragma warning(disable: 4290)
43 
44 #ifdef _COMDEF_NOT_WINAPI_FAMILY_DESKTOP_APP
45 
46 #include <roerrorapi.h>
47 #include <new.h>
48 #include <wchar.h>
49 
50 inline void __stdcall _com_issue_error(HRESULT hr);
51 
52 class _com_error
53 {
54 protected:
55  static wchar_t* AllocateString(const wchar_t* message)
56  {
57  wchar_t* value = nullptr;
58  if (message != nullptr)
59  {
60  auto length = ::wcslen(message) + 1; // add 1 for null terminator
61  value = new (std::nothrow) wchar_t[length];
62  if (value == nullptr)
63  {
64  _com_issue_error(E_OUTOFMEMORY);
65  }
66 
67  ::wmemcpy(value, message, length);
68  }
69 
70  return value;
71  }
72 public:
73  _com_error(HRESULT hr, const wchar_t* message) : m_hr(hr), m_message(nullptr)
74  {
75  m_message = AllocateString(message);
76  }
77 
78  _com_error(const _com_error& other)
79  {
80  m_hr = other.m_hr;
81  m_message = AllocateString(other.m_message);
82  }
83 
84  _com_error(_com_error&& other)
85  {
86  m_hr = other.m_hr;
87  m_message = other.m_message;
88  other.m_message = nullptr;
89  }
90 
91  ~_com_error() throw()
92  {
93  delete [] m_message;
94  }
95 
96  _com_error& operator=(const _com_error& other)
97  {
98  if (this != &other)
99  {
100  m_hr = other.m_hr;
101  delete [] m_message;
102  m_message = AllocateString(other.m_message);
103  }
104  return *this;
105  }
106 
108  {
109  if (this != &other)
110  {
111  m_hr = other.m_hr;
112  delete [] m_message;
113  m_message = other.m_message;
114  other.m_message = nullptr;
115  }
116  return *this;
117  }
118 
119  HRESULT Error() const throw()
120  {
121  return m_hr;
122  }
123 
124  const wchar_t* ErrorMessage() const throw()
125  {
126  if (m_message == nullptr)
127  {
128  wchar_t buffer[4096];
129  if (::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
130  nullptr,
131  m_hr,
132  MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
133  buffer,
134  _countof(buffer),
135  nullptr))
136  {
137  m_message = AllocateString(buffer);
138  }
139  }
140  return m_message;
141  }
142 protected:
143  HRESULT m_hr;
144  mutable wchar_t* m_message;
145 };
146 
147 inline void __declspec(noreturn) __stdcall _com_raise_error(HRESULT hr, const wchar_t* message)
148 {
149  size_t length = (message == nullptr) ? 0 : ::wcslen(message);
150 
151  if (UINT_MAX < length)
152  {
153  length = 0;
154  }
155 
156  ::Windows::Foundation::Diagnostics::OriginateError(hr, static_cast<unsigned int>(length), message);
157  throw _com_error(hr, message);
158 }
159 
160 typedef void (__stdcall *__errorPfnType)(HRESULT hr, const wchar_t* message);
161 
162 // throw exceptions by default
163 __declspec(selectany) __errorPfnType __errorPfn = &_com_raise_error;
164 
165 inline void __stdcall _com_issue_errorex(HRESULT hr, const wchar_t* message)
166 {
167  __errorPfn(hr, message);
168 }
169 
170 inline void __stdcall _com_issue_error(HRESULT hr)
171 {
172  __errorPfn(hr, nullptr);
173 }
174 
175 inline void __stdcall _set_com_error_handler(void (__stdcall *pHandler)(HRESULT, const wchar_t*))
176 {
177  __errorPfn = pHandler;
178 }
179 
180 #else
181 
182 #include <olectl.h>
183 
184 #ifdef _NATIVE_WCHAR_T_DEFINED
185 # ifdef _DEBUG
186 # pragma comment(lib, "comsuppwd.lib")
187 # else
188 # pragma comment(lib, "comsuppw.lib")
189 # endif
190 #else
191 # ifdef _DEBUG
192 # pragma comment(lib, "comsuppd.lib")
193 # else
194 # pragma comment(lib, "comsupp.lib")
195 # endif
196 #endif
197 
198 #pragma comment(lib, "user32.lib")
199 #pragma comment(lib, "ole32.lib")
200 #pragma comment(lib, "oleaut32.lib")
201 
202 class _com_error;
203 
204 void __declspec(noreturn) __stdcall
205  _com_raise_error(HRESULT hr, IErrorInfo* perrinfo = 0) ;
206 
207 void __stdcall
208  _set_com_error_handler(void (__stdcall *pHandler)(HRESULT hr, IErrorInfo* perrinfo));
209 
210 void __stdcall
211  _com_issue_error(HRESULT) ;
212 void __stdcall
213  _com_issue_errorex(HRESULT, IUnknown*, REFIID) ;
214 
215 HRESULT __stdcall
216  _com_dispatch_propget(IDispatch*, DISPID, VARTYPE, void*) ;
217 HRESULT __cdecl
218  _com_dispatch_propput(IDispatch*, DISPID, VARTYPE, ...) ;
219 HRESULT __cdecl
220  _com_dispatch_method(IDispatch*, DISPID, WORD, VARTYPE, void*,
221  const wchar_t*, ...) ;
222 
223 HRESULT __stdcall
224  _com_dispatch_raw_propget(IDispatch*, DISPID, VARTYPE, void*) throw();
225 HRESULT __cdecl
226  _com_dispatch_raw_propput(IDispatch*, DISPID, VARTYPE, ...) throw();
227 HRESULT __cdecl
228  _com_dispatch_raw_method(IDispatch*, DISPID, WORD, VARTYPE, void*,
229  const wchar_t*, ...) throw();
230 
231 class _com_error {
232 public:
233  // Constructors
234  //
235  _com_error(HRESULT hr,
236  IErrorInfo* perrinfo = NULL,
237  bool fAddRef = false) throw();
238  _com_error(const _com_error& that) throw();
239 
240  // Destructor
241  //
242  virtual ~_com_error() throw();
243 
244  // Assignment operator
245  //
246  _com_error& operator=(const _com_error& that) throw();
247 
248  // Accessors
249  //
250  HRESULT Error() const throw();
251  WORD WCode() const throw();
252  IErrorInfo * ErrorInfo() const throw();
253 
254  // IErrorInfo method accessors
255  //
256  _bstr_t Description() const ;
257  DWORD HelpContext() const throw();
258  _bstr_t HelpFile() const ;
259  _bstr_t Source() const ;
260  GUID GUID() const throw();
261 
262  // FormatMessage accessors
263  //
264  const TCHAR * ErrorMessage() const throw();
265 
266  // EXCEPINFO.wCode <-> HRESULT mappers
267  //
268  static HRESULT WCodeToHRESULT(WORD wCode) throw();
269  static WORD HRESULTToWCode(HRESULT hr) throw();
270 
271 private:
272  enum {
273  WCODE_HRESULT_FIRST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x200),
274  WCODE_HRESULT_LAST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF+1, 0) - 1
275  };
276  const HRESULT m_hresult;
277  IErrorInfo * m_perrinfo;
278  mutable TCHAR * m_pszMsg;
279 };
280 
281 inline _com_error::_com_error(HRESULT hr,
282  IErrorInfo* perrinfo,
283  bool fAddRef) throw()
285 {
286  if (m_perrinfo != NULL && fAddRef) {
287  m_perrinfo->AddRef();
288  }
289 }
290 
291 inline _com_error::_com_error(const _com_error& that) throw()
292  : m_hresult(that.m_hresult), m_perrinfo(that.m_perrinfo), m_pszMsg(NULL)
293 {
294  if (m_perrinfo != NULL) {
295  m_perrinfo->AddRef();
296  }
297 }
298 
299 inline _com_error::~_com_error() throw()
300 {
301  if (m_perrinfo != NULL) {
302  m_perrinfo->Release();
303  }
304  if (m_pszMsg != NULL) {
305  LocalFree((HLOCAL)m_pszMsg);
306  }
307 }
308 
309 inline _com_error& _com_error::operator=(const _com_error& that) throw()
310 {
311  if (this != &that) {
312  this->_com_error::~_com_error();
313  this->_com_error::_com_error(that);
314  }
315  return *this;
316 }
317 
318 inline HRESULT _com_error::Error() const throw()
319 {
320  return m_hresult;
321 }
322 
323 inline WORD _com_error::WCode() const throw()
324 {
325  return HRESULTToWCode(m_hresult);
326 }
327 
328 inline IErrorInfo * _com_error::ErrorInfo() const throw()
329 {
330  if (m_perrinfo != NULL) {
331  m_perrinfo->AddRef();
332  }
333  return m_perrinfo;
334 }
335 
337 {
338  BSTR bstr = NULL;
339  if (m_perrinfo != NULL) {
340  if (FAILED(m_perrinfo->GetDescription(&bstr))) {
341  bstr = NULL;
342  }
343  }
344  return _bstr_t(bstr, false);
345 }
346 
347 inline DWORD _com_error::HelpContext() const throw()
348 {
349  DWORD dwHelpContext = 0;
350  if (m_perrinfo != NULL) {
351  if (FAILED(m_perrinfo->GetHelpContext(&dwHelpContext))) {
352  dwHelpContext = 0;
353  }
354  }
355  return dwHelpContext;
356 }
357 
359 {
360  BSTR bstr = NULL;
361  if (m_perrinfo != NULL) {
362  if (FAILED(m_perrinfo->GetHelpFile(&bstr))) {
363  bstr = NULL;
364  }
365  }
366  return _bstr_t(bstr, false);
367 }
368 
370 {
371  BSTR bstr = NULL;
372  if (m_perrinfo != NULL) {
373  if (FAILED(m_perrinfo->GetSource(&bstr))) {
374  bstr = NULL;
375  }
376  }
377  return _bstr_t(bstr, false);
378 }
379 
380 inline _GUID _com_error::GUID() const throw()
381 {
382  _GUID guid;
383  _COM_MEMCPY_S(&guid, sizeof(_GUID), &__uuidof(NULL), sizeof(_GUID));
384  if (m_perrinfo != NULL) {
385  if (FAILED(m_perrinfo->GetGUID(&guid))) {
386  _COM_MEMCPY_S(&guid, sizeof(_GUID), &__uuidof(NULL), sizeof(_GUID));
387  }
388  }
389  return guid;
390 }
391 
392 inline const TCHAR * _com_error::ErrorMessage() const throw()
393 {
394  if (m_pszMsg == NULL) {
395  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
396  FORMAT_MESSAGE_FROM_SYSTEM|
397  FORMAT_MESSAGE_IGNORE_INSERTS,
398  NULL,
399  m_hresult,
400  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
401  (LPTSTR)&m_pszMsg,
402  0,
403  NULL);
404  if (m_pszMsg != NULL) {
405  int nLen = lstrlen(m_pszMsg);
406  if (nLen > 1 && m_pszMsg[nLen - 1] == '\n') {
407  m_pszMsg[nLen - 1] = 0;
408  if (m_pszMsg[nLen - 2] == '\r') {
409  m_pszMsg[nLen - 2] = 0;
410  }
411  }
412  }
413  else {
414  m_pszMsg = (LPTSTR)LocalAlloc(0, 32 * sizeof(TCHAR));
415  if (m_pszMsg != NULL) {
416  WORD wCode = WCode();
417  if (wCode != 0) {
418  _COM_PRINTF_S_1(m_pszMsg, 32, TEXT("IDispatch error #%d"), (int)wCode);
419  }
420  else {
421  _COM_PRINTF_S_1(m_pszMsg, 32, TEXT("Unknown error 0x%0lX"), m_hresult);
422  }
423  }
424  }
425  }
426  return m_pszMsg;
427 }
428 
429 inline HRESULT _com_error::WCodeToHRESULT(WORD wCode) throw()
430 {
431  return wCode >= 0xFE00 ? WCODE_HRESULT_LAST : WCODE_HRESULT_FIRST + wCode;
432 }
433 
434 inline WORD _com_error::HRESULTToWCode(HRESULT hr) throw()
435 {
436  return (hr >= WCODE_HRESULT_FIRST && hr <= WCODE_HRESULT_LAST)
437  ? WORD(hr - WCODE_HRESULT_FIRST)
438  : 0;
439 }
440 
441 //
442 // give missing types from dependent type libraries a chance
443 //
444 typedef int __missing_type__;
445 
446 #if !defined(_COM_SMARTPTR)
447  #if !defined(_INC_COMIP)
448  #include <comip.h>
449  #endif
450  #define _COM_SMARTPTR _com_ptr_t
451  #define _COM_SMARTPTR_LEVEL2 _com_IIID
452 #endif
453 #if defined(_COM_SMARTPTR)
454  #if !defined(_COM_SMARTPTR_TYPEDEF)
455  #if defined(_COM_SMARTPTR_LEVEL2)
456  #define _COM_SMARTPTR_TYPEDEF(Interface, IID) \
457  typedef _COM_SMARTPTR<_COM_SMARTPTR_LEVEL2<Interface, &IID> > \
458  Interface ## Ptr
459  #else
460  #define _COM_SMARTPTR_TYPEDEF(Interface, IID) \
461  typedef _COM_SMARTPTR<Interface, &IID> \
462  Interface ## Ptr
463  #endif
464  #endif
465 #endif
466 
467 #if !defined(_COM_NO_STANDARD_GUIDS_)
468 
469 // hard-coded smart pointer defs
470 #if defined(__IFontDisp_INTERFACE_DEFINED__)
471 __if_not_exists(Font)
472 {
473  struct Font : IFontDisp {};
474 }
475 _COM_SMARTPTR_TYPEDEF(Font, __uuidof(IDispatch));
476 #endif
477 #if defined(__IFontEventsDisp_INTERFACE_DEFINED__)
478 __if_not_exists(FontEvents)
479 {
480  struct FontEvents : IFontEventsDisp {};
481 }
482 _COM_SMARTPTR_TYPEDEF(FontEvents, __uuidof(IDispatch));
483 #endif
484 #if defined(__IPictureDisp_INTERFACE_DEFINED__)
485 __if_not_exists(Picture)
486 {
487  struct Picture : IPictureDisp {};
488 }
489 _COM_SMARTPTR_TYPEDEF(Picture, __uuidof(IDispatch));
490 #endif
491 
492 #include "comdefsp.h"
493 
494 #endif /* _COM_NO_STANDARD_GUIDS_ */
495 
496 #endif /* _COMDEF_NOT_WINAPI_FAMILY_DESKTOP_APP */
497 
498 #pragma warning(pop)
499 
500 #endif /* RC_INVOKED */
501 #endif /* _INC_COMDEF */
Definition: comutil.h:144
Definition: comdef.h:231
void __stdcall _set_com_error_handler(void(__stdcall *pHandler)(HRESULT hr, IErrorInfo *perrinfo))
const HRESULT m_hresult
Definition: comdef.h:276
_Check_return_ _CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_bstr_t HelpFile() const
Definition: comdef.h:358
HRESULT __cdecl _com_dispatch_propput(IDispatch *, DISPID, VARTYPE,...)
char TCHAR
Definition: tchar.h:2138
TCHAR * m_pszMsg
Definition: comdef.h:278
typedef void(__cdecl *_se_translator_function)(unsigned int
void __stdcall _com_issue_errorex(HRESULT, IUnknown *, REFIID)
HRESULT __stdcall _com_dispatch_raw_propget(IDispatch *, DISPID, VARTYPE, void *)
#define NULL
Definition: crtdbg.h:30
#define _countof(_Array)
Definition: stdlib.h:359
#define _COM_PRINTF_S_1(dest, destsize, format, arg1)
Definition: comutil.h:49
#define UINT_MAX
Definition: limits.h:41
HRESULT __cdecl _com_dispatch_raw_propput(IDispatch *, DISPID, VARTYPE,...)
virtual ~_com_error()
Definition: comdef.h:299
void __stdcall _com_issue_error(HRESULT)
#define FAILED(hr)
Definition: comutil.h:71
_bstr_t Description() const
Definition: comdef.h:336
HRESULT __cdecl _com_dispatch_method(IDispatch *, DISPID, WORD, VARTYPE, void *, const wchar_t *,...)
IErrorInfo * ErrorInfo() const
Definition: comdef.h:328
REFIID
Definition: agile.h:27
WORD WCode() const
Definition: comdef.h:323
_com_error & operator=(const _com_error &that)
Definition: comdef.h:309
_bstr_t Source() const
Definition: comdef.h:369
unsigned long DWORD
Definition: concrt.h:57
HRESULT __cdecl _com_dispatch_raw_method(IDispatch *, DISPID, WORD, VARTYPE, void *, const wchar_t *,...)
static WORD HRESULTToWCode(HRESULT hr)
Definition: comdef.h:434
HRESULT __stdcall _com_dispatch_propget(IDispatch *, DISPID, VARTYPE, void *)
int __missing_type__
Definition: comdef.h:444
static HRESULT WCodeToHRESULT(WORD wCode)
Definition: comdef.h:429
Definition: comdef.h:273
#define _COM_MEMCPY_S(dest, destsize, src, count)
Definition: comutil.h:48
const TCHAR * ErrorMessage() const
Definition: comdef.h:392
void IErrorInfo * perrinfo
Definition: comdef.h:205
#define _COM_SMARTPTR_TYPEDEF(Interface, IID)
Definition: comdef.h:456
DWORD HelpContext() const
Definition: comdef.h:347
IErrorInfo * m_perrinfo
Definition: comdef.h:277
HRESULT Error() const
Definition: comdef.h:318
Definition: comdef.h:274
void __declspec(noreturn) __stdcall _com_raise_error(HRESULT hr
_com_error(HRESULT hr, IErrorInfo *perrinfo=NULL, bool fAddRef=false)
Definition: comdef.h:281
GUID GUID() const
Definition: comdef.h:380
const nothrow_t nothrow