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 #if defined(_GUARDED_CRT)
186 # ifdef _DEBUG
187 # pragma comment(lib, "comsuppwgd.lib")
188 # else
189 # pragma comment(lib, "comsuppwg.lib")
190 # endif
191 #else
192 # ifdef _DEBUG
193 # pragma comment(lib, "comsuppwd.lib")
194 # else
195 # pragma comment(lib, "comsuppw.lib")
196 # endif
197 #endif
198 #else
199 #if defined(_GUARDED_CRT)
200 # ifdef _DEBUG
201 # pragma comment(lib, "comsuppgd.lib")
202 # else
203 # pragma comment(lib, "comsuppg.lib")
204 # endif
205 #else
206 # ifdef _DEBUG
207 # pragma comment(lib, "comsuppd.lib")
208 # else
209 # pragma comment(lib, "comsupp.lib")
210 # endif
211 #endif
212 #endif
213 
214 #pragma comment(lib, "user32.lib")
215 #pragma comment(lib, "ole32.lib")
216 #pragma comment(lib, "oleaut32.lib")
217 
218 class _com_error;
219 
220 void __declspec(noreturn) __stdcall
221  _com_raise_error(HRESULT hr, IErrorInfo* perrinfo = 0) ;
222 
223 void __stdcall
224  _set_com_error_handler(void (__stdcall *pHandler)(HRESULT hr, IErrorInfo* perrinfo));
225 
226 void __stdcall
227  _com_issue_error(HRESULT) ;
228 void __stdcall
229  _com_issue_errorex(HRESULT, IUnknown*, REFIID) ;
230 
231 HRESULT __stdcall
232  _com_dispatch_propget(IDispatch*, DISPID, VARTYPE, void*) ;
233 HRESULT __cdecl
234  _com_dispatch_propput(IDispatch*, DISPID, VARTYPE, ...) ;
235 HRESULT __cdecl
236  _com_dispatch_method(IDispatch*, DISPID, WORD, VARTYPE, void*,
237  const wchar_t*, ...) ;
238 
239 HRESULT __stdcall
240  _com_dispatch_raw_propget(IDispatch*, DISPID, VARTYPE, void*) throw();
241 HRESULT __cdecl
242  _com_dispatch_raw_propput(IDispatch*, DISPID, VARTYPE, ...) throw();
243 HRESULT __cdecl
244  _com_dispatch_raw_method(IDispatch*, DISPID, WORD, VARTYPE, void*,
245  const wchar_t*, ...) throw();
246 
247 class _com_error {
248 public:
249  // Constructors
250  //
251  _com_error(HRESULT hr,
252  IErrorInfo* perrinfo = NULL,
253  bool fAddRef = false) throw();
254  _com_error(const _com_error& that) throw();
255 
256  // Destructor
257  //
258  virtual ~_com_error() throw();
259 
260  // Assignment operator
261  //
262  _com_error& operator=(const _com_error& that) throw();
263 
264  // Accessors
265  //
266  HRESULT Error() const throw();
267  WORD WCode() const throw();
268  IErrorInfo * ErrorInfo() const throw();
269 
270  // IErrorInfo method accessors
271  //
272  _bstr_t Description() const ;
273  DWORD HelpContext() const throw();
274  _bstr_t HelpFile() const ;
275  _bstr_t Source() const ;
276  GUID GUID() const throw();
277 
278  // FormatMessage accessors
279  //
280  const TCHAR * ErrorMessage() const throw();
281 
282  // EXCEPINFO.wCode <-> HRESULT mappers
283  //
284  static HRESULT WCodeToHRESULT(WORD wCode) throw();
285  static WORD HRESULTToWCode(HRESULT hr) throw();
286 
287 private:
288  enum {
289  WCODE_HRESULT_FIRST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x200),
290  WCODE_HRESULT_LAST = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF+1, 0) - 1
291  };
292  const HRESULT m_hresult;
293  IErrorInfo * m_perrinfo;
294  mutable TCHAR * m_pszMsg;
295 };
296 
297 inline _com_error::_com_error(HRESULT hr,
298  IErrorInfo* perrinfo,
299  bool fAddRef) throw()
301 {
302  if (m_perrinfo != NULL && fAddRef) {
303  m_perrinfo->AddRef();
304  }
305 }
306 
307 inline _com_error::_com_error(const _com_error& that) throw()
308  : m_hresult(that.m_hresult), m_perrinfo(that.m_perrinfo), m_pszMsg(NULL)
309 {
310  if (m_perrinfo != NULL) {
311  m_perrinfo->AddRef();
312  }
313 }
314 
315 inline _com_error::~_com_error() throw()
316 {
317  if (m_perrinfo != NULL) {
318  m_perrinfo->Release();
319  }
320  if (m_pszMsg != NULL) {
321  LocalFree((HLOCAL)m_pszMsg);
322  }
323 }
324 
325 inline _com_error& _com_error::operator=(const _com_error& that) throw()
326 {
327  if (this != &that) {
328  this->_com_error::~_com_error();
329  this->_com_error::_com_error(that);
330  }
331  return *this;
332 }
333 
334 inline HRESULT _com_error::Error() const throw()
335 {
336  return m_hresult;
337 }
338 
339 inline WORD _com_error::WCode() const throw()
340 {
341  return HRESULTToWCode(m_hresult);
342 }
343 
344 inline IErrorInfo * _com_error::ErrorInfo() const throw()
345 {
346  if (m_perrinfo != NULL) {
347  m_perrinfo->AddRef();
348  }
349  return m_perrinfo;
350 }
351 
353 {
354  BSTR bstr = NULL;
355  if (m_perrinfo != NULL) {
356  if (FAILED(m_perrinfo->GetDescription(&bstr))) {
357  bstr = NULL;
358  }
359  }
360  return _bstr_t(bstr, false);
361 }
362 
363 inline DWORD _com_error::HelpContext() const throw()
364 {
365  DWORD dwHelpContext = 0;
366  if (m_perrinfo != NULL) {
367  if (FAILED(m_perrinfo->GetHelpContext(&dwHelpContext))) {
368  dwHelpContext = 0;
369  }
370  }
371  return dwHelpContext;
372 }
373 
375 {
376  BSTR bstr = NULL;
377  if (m_perrinfo != NULL) {
378  if (FAILED(m_perrinfo->GetHelpFile(&bstr))) {
379  bstr = NULL;
380  }
381  }
382  return _bstr_t(bstr, false);
383 }
384 
386 {
387  BSTR bstr = NULL;
388  if (m_perrinfo != NULL) {
389  if (FAILED(m_perrinfo->GetSource(&bstr))) {
390  bstr = NULL;
391  }
392  }
393  return _bstr_t(bstr, false);
394 }
395 
396 inline _GUID _com_error::GUID() const throw()
397 {
398  _GUID guid{};
399  if (m_perrinfo != NULL) {
400  if (FAILED(m_perrinfo->GetGUID(&guid))) {
401  guid = _GUID{};
402  }
403  }
404  return guid;
405 }
406 
407 inline const TCHAR * _com_error::ErrorMessage() const throw()
408 {
409  if (m_pszMsg == NULL) {
410  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
411  FORMAT_MESSAGE_FROM_SYSTEM|
412  FORMAT_MESSAGE_IGNORE_INSERTS,
413  NULL,
414  m_hresult,
415  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
416  (LPTSTR)&m_pszMsg,
417  0,
418  NULL);
419  if (m_pszMsg != NULL) {
420  #ifdef UNICODE
421  size_t const nLen = wcslen(m_pszMsg);
422  #else
423  size_t const nLen = strlen(m_pszMsg);
424  #endif
425  if (nLen > 1 && m_pszMsg[nLen - 1] == '\n') {
426  m_pszMsg[nLen - 1] = 0;
427  if (m_pszMsg[nLen - 2] == '\r') {
428  m_pszMsg[nLen - 2] = 0;
429  }
430  }
431  }
432  else {
433  m_pszMsg = (LPTSTR)LocalAlloc(0, 32 * sizeof(TCHAR));
434  if (m_pszMsg != NULL) {
435  WORD wCode = WCode();
436  if (wCode != 0) {
437  _COM_PRINTF_S_1(m_pszMsg, 32, TEXT("IDispatch error #%d"), (int)wCode);
438  }
439  else {
440  _COM_PRINTF_S_1(m_pszMsg, 32, TEXT("Unknown error 0x%0lX"), m_hresult);
441  }
442  }
443  }
444  }
445  return m_pszMsg;
446 }
447 
448 inline HRESULT _com_error::WCodeToHRESULT(WORD wCode) throw()
449 {
450  return wCode >= 0xFE00 ? WCODE_HRESULT_LAST : WCODE_HRESULT_FIRST + wCode;
451 }
452 
453 inline WORD _com_error::HRESULTToWCode(HRESULT hr) throw()
454 {
455  return (hr >= WCODE_HRESULT_FIRST && hr <= WCODE_HRESULT_LAST)
456  ? WORD(hr - WCODE_HRESULT_FIRST)
457  : 0;
458 }
459 
460 //
461 // give missing types from dependent type libraries a chance
462 //
463 typedef int __missing_type__;
464 
465 #if !defined(_COM_SMARTPTR)
466  #if !defined(_INC_COMIP)
467  #include <comip.h>
468  #endif
469  #define _COM_SMARTPTR _com_ptr_t
470  #define _COM_SMARTPTR_LEVEL2 _com_IIID
471 #endif
472 #if defined(_COM_SMARTPTR)
473  #if !defined(_COM_SMARTPTR_TYPEDEF)
474  #if defined(_COM_SMARTPTR_LEVEL2)
475  #define _COM_SMARTPTR_TYPEDEF(Interface, IID) \
476  typedef _COM_SMARTPTR<_COM_SMARTPTR_LEVEL2<Interface, &IID> > \
477  Interface ## Ptr
478  #else
479  #define _COM_SMARTPTR_TYPEDEF(Interface, IID) \
480  typedef _COM_SMARTPTR<Interface, &IID> \
481  Interface ## Ptr
482  #endif
483  #endif
484 #endif
485 
486 #if !defined(_COM_NO_STANDARD_GUIDS_)
487 
488 // hard-coded smart pointer defs
489 #if defined(__IFontDisp_INTERFACE_DEFINED__)
490 __if_not_exists(Font)
491 {
492  struct Font : IFontDisp {};
493 }
494 _COM_SMARTPTR_TYPEDEF(Font, __uuidof(IDispatch));
495 #endif
496 #if defined(__IFontEventsDisp_INTERFACE_DEFINED__)
497 __if_not_exists(FontEvents)
498 {
499  struct FontEvents : IFontEventsDisp {};
500 }
501 _COM_SMARTPTR_TYPEDEF(FontEvents, __uuidof(IDispatch));
502 #endif
503 #if defined(__IPictureDisp_INTERFACE_DEFINED__)
504 __if_not_exists(Picture)
505 {
506  struct Picture : IPictureDisp {};
507 }
508 _COM_SMARTPTR_TYPEDEF(Picture, __uuidof(IDispatch));
509 #endif
510 
511 #include "comdefsp.h"
512 
513 #endif /* _COM_NO_STANDARD_GUIDS_ */
514 
515 #endif /* _COMDEF_NOT_WINAPI_FAMILY_DESKTOP_APP */
516 
517 #pragma warning(pop)
518 
519 #endif /* RC_INVOKED */
520 #endif /* _INC_COMDEF */
Definition: comdef.h:290
Definition: comutil.h:144
Definition: comdef.h:247
void __stdcall _set_com_error_handler(void(__stdcall *pHandler)(HRESULT hr, IErrorInfo *perrinfo))
#define NULL
Definition: vcruntime.h:236
const HRESULT m_hresult
Definition: comdef.h:292
Definition: comdef.h:289
_bstr_t HelpFile() const
Definition: comdef.h:374
HRESULT __cdecl _com_dispatch_propput(IDispatch *, DISPID, VARTYPE,...)
TCHAR * m_pszMsg
Definition: comdef.h:294
void __stdcall _com_issue_errorex(HRESULT, IUnknown *, REFIID)
HRESULT __stdcall _com_dispatch_raw_propget(IDispatch *, DISPID, VARTYPE, void *)
#define _COM_PRINTF_S_1(dest, destsize, format, arg1)
Definition: comutil.h:49
#define UINT_MAX
Definition: limits.h:36
HRESULT __cdecl _com_dispatch_raw_propput(IDispatch *, DISPID, VARTYPE,...)
virtual ~_com_error()
Definition: comdef.h:315
void __stdcall _com_issue_error(HRESULT)
#define FAILED(hr)
Definition: comutil.h:71
_bstr_t Description() const
Definition: comdef.h:352
HRESULT __cdecl _com_dispatch_method(IDispatch *, DISPID, WORD, VARTYPE, void *, const wchar_t *,...)
IErrorInfo * ErrorInfo() const
Definition: comdef.h:344
WORD WCode() const
Definition: comdef.h:339
_com_error & operator=(const _com_error &that)
Definition: comdef.h:325
_bstr_t Source() const
Definition: comdef.h:385
unsigned long DWORD
Definition: concrt.h:63
HRESULT __cdecl _com_dispatch_raw_method(IDispatch *, DISPID, WORD, VARTYPE, void *, const wchar_t *,...)
static WORD HRESULTToWCode(HRESULT hr)
Definition: comdef.h:453
HRESULT __stdcall _com_dispatch_propget(IDispatch *, DISPID, VARTYPE, void *)
int __missing_type__
Definition: comdef.h:463
static HRESULT WCodeToHRESULT(WORD wCode)
Definition: comdef.h:448
const TCHAR * ErrorMessage() const
Definition: comdef.h:407
void IErrorInfo * perrinfo
Definition: comdef.h:221
#define _COM_SMARTPTR_TYPEDEF(Interface, IID)
Definition: comdef.h:475
DWORD HelpContext() const
Definition: comdef.h:363
_CRT_BEGIN_C_HEADER typedef void(__CRTDECL *unexpected_handler)()
IErrorInfo * m_perrinfo
Definition: comdef.h:293
HRESULT Error() const
Definition: comdef.h:334
void __declspec(noreturn) __stdcall _com_raise_error(HRESULT hr
_com_error(HRESULT hr, IErrorInfo *perrinfo=NULL, bool fAddRef=false)
Definition: comdef.h:297
GUID GUID() const
Definition: comdef.h:396