STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
comip.h
Go to the documentation of this file.
1 /***
2 * comip.h - Native C++ compiler COM support - COM interface pointers 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 #ifdef _M_CEE_PURE
13 #error comip.h header cannot be included under /clr:safe or /clr:pure
14 #endif
15 
16 #if !defined(_INC_COMIP)
17 #define _INC_COMIP
18 
19 #include <ole2.h>
20 #include <malloc.h>
21 
22 #include <comutil.h>
23 
24 #pragma warning(push)
25 #pragma warning(disable: 4290)
26 
27 #pragma push_macro("new")
28 #undef new
29 
30 #include <new.h>
31 
32 class _com_error;
33 
34 void __stdcall _com_issue_error(HRESULT);
35 struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown;
36 
37 // Provide Interface to IID association
38 //
39 template<typename _Interface, const IID* _IID /*= &__uuidof(_Interface)*/>
40 class _com_IIID {
41 public:
42  typedef _Interface Interface;
43 
44  static _Interface* GetInterfacePtr() throw()
45  {
46  return NULL;
47  }
48 
49  static _Interface& GetInterface() throw()
50  {
51  return *GetInterfacePtr();
52  }
53 
54  static const IID& GetIID() throw()
55  {
56  return *_IID;
57  }
58 };
59 
60 template<typename _IIID> class _com_ptr_t {
61 public:
62  // Declare interface type so that the type may be available outside
63  // the scope of this template.
64  //
65  typedef _IIID ThisIIID;
66  typedef typename _IIID::Interface Interface;
67 
68  // When the compiler supports references in template parameters,
69  // _CLSID will be changed to a reference. To avoid conversion
70  // difficulties this function should be used to obtain the
71  // CLSID.
72  //
73  static const IID& GetIID() throw()
74  {
75  return ThisIIID::GetIID();
76  }
77 
78  // Constructs a smart-pointer from any other smart pointer.
79  //
80  template<typename _OtherIID> _com_ptr_t(const _com_ptr_t<_OtherIID>& p)
82  {
83  HRESULT hr = _QueryInterface(p);
84 
85  if (FAILED(hr) && (hr != E_NOINTERFACE)) {
86  _com_issue_error(hr);
87  }
88  }
89 
90  // Constructs a smart-pointer from any IUnknown-based interface pointer.
91  //
92  template<typename _InterfaceType> _com_ptr_t(_InterfaceType* p)
94  {
95  HRESULT hr = _QueryInterface(p);
96 
97  if (FAILED(hr) && (hr != E_NOINTERFACE)) {
98  _com_issue_error(hr);
99  }
100  }
101 
102  // Make sure correct ctor is called
103  //
104  template<> _com_ptr_t(_In_ LPSTR str)
105  {
106  new(this) _com_ptr_t(static_cast<LPCSTR> (str), NULL);
107  }
108 
109  // Make sure correct ctor is called
110  //
111  template<> _com_ptr_t(_In_ LPWSTR str)
112  {
113  new(this) _com_ptr_t(static_cast<LPCWSTR> (str), NULL);
114  }
115 
116  // Disable conversion using _com_ptr_t* specialization of
117  // template<typename _InterfaceType> _com_ptr_t(_InterfaceType* p)
118  //
119  template<> explicit _com_ptr_t(_com_ptr_t* p)
120  : m_pInterface(NULL)
121  {
122  if (p == NULL) {
123  _com_issue_error(E_POINTER);
124  }
125  else {
127  AddRef();
128  }
129  }
130 
131  // Default constructor.
132  //
133  _com_ptr_t() throw()
134  : m_pInterface(NULL)
135  {
136  }
137 
138  // This constructor is provided to allow NULL assignment. It will issue
139  // an error if any value other than null is assigned to the object.
140  //
141  _com_ptr_t(int null)
142  : m_pInterface(NULL)
143  {
144  if (null != 0) {
145  _com_issue_error(E_POINTER);
146  }
147  }
148 
149 #if defined(_NATIVE_NULLPTR_SUPPORTED) && !defined(_DO_NOT_USE_NULLPTR_IN_COM_PTR_T)
150 
151  // This constructor is provided to allow nullptr assignment.
152  _com_ptr_t(decltype(__nullptr)) : m_pInterface(NULL) { }
153 
154 #endif // defined(_NATIVE_NULLPTR_SUPPORTED) && !defined(_DO_NOT_USE_NULLPTR_IN_COM_PTR_T)
155 
156  // Copy the pointer and AddRef().
157  //
158  _com_ptr_t(const _com_ptr_t& cp) throw()
159  : m_pInterface(cp.m_pInterface)
160  {
161  _AddRef();
162  }
163 
164  // Move the pointer.
165  //
166  _com_ptr_t(_com_ptr_t&& cp) throw()
168  {
169  cp.m_pInterface = nullptr;
170  }
171 
172  // Saves the interface.
173  //
174  template<> _com_ptr_t(Interface* pInterface) throw()
175  : m_pInterface(pInterface)
176  {
177  _AddRef();
178  }
179 
180  // Copies the pointer. If fAddRef is TRUE, the interface will
181  // be AddRef()ed.
182  //
183  _com_ptr_t(Interface* pInterface, bool fAddRef) throw()
184  : m_pInterface(pInterface)
185  {
186  if (fAddRef) {
187  _AddRef();
188  }
189  }
190 
191  // Construct a pointer for a _variant_t object.
192  //
193  _com_ptr_t(const _variant_t& varSrc)
194  : m_pInterface(NULL)
195  {
196  HRESULT hr = QueryStdInterfaces(varSrc);
197 
198  if (FAILED(hr) && (hr != E_NOINTERFACE)) {
199  _com_issue_error(hr);
200  }
201  }
202 
203  // Calls CoCreateClass with the provided CLSID.
204  //
205  explicit _com_ptr_t(const CLSID& clsid, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
206  : m_pInterface(NULL)
207  {
208  HRESULT hr = CreateInstance(clsid, pOuter, dwClsContext);
209 
210  if (FAILED(hr) && (hr != E_NOINTERFACE)) {
211  _com_issue_error(hr);
212  }
213  }
214 
215  // Calls CoCreateClass with the provided CLSID retrieved from
216  // the string.
217  //
218  explicit _com_ptr_t(LPCWSTR str, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
219  : m_pInterface(NULL)
220  {
221  HRESULT hr = CreateInstance(str, pOuter, dwClsContext);
222 
223  if (FAILED(hr) && (hr != E_NOINTERFACE)) {
224  _com_issue_error(hr);
225  }
226  }
227 
228  // Calls CoCreateClass with the provided SBCS CLSID retrieved from
229  // the string.
230  //
231  explicit _com_ptr_t(LPCSTR str, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
232  : m_pInterface(NULL)
233  {
234  HRESULT hr = CreateInstance(str, pOuter, dwClsContext);
235 
236  if (FAILED(hr) && (hr != E_NOINTERFACE)) {
237  _com_issue_error(hr);
238  }
239  }
240 
241  // Queries for interface.
242  //
243  template<typename _OtherIID> _com_ptr_t& operator=(const _com_ptr_t<_OtherIID>& p)
244  {
245  HRESULT hr = _QueryInterface(p);
246 
247  if (FAILED(hr) && (hr != E_NOINTERFACE)) {
248  _com_issue_error(hr);
249  }
250 
251  return *this;
252  }
253 
254  // Queries for interface.
255  //
256  template<typename _InterfaceType> _com_ptr_t& operator=(_InterfaceType* p)
257  {
258  HRESULT hr = _QueryInterface(p);
259 
260  if (FAILED(hr) && (hr != E_NOINTERFACE)) {
261  _com_issue_error(hr);
262  }
263 
264  return *this;
265  }
266 
267  // Saves the interface.
268  //
269  template<> _com_ptr_t& operator=(Interface* pInterface) throw()
270  {
271  if (m_pInterface != pInterface) {
272  Interface* pOldInterface = m_pInterface;
273 
274  m_pInterface = pInterface;
275 
276  _AddRef();
277 
278  if (pOldInterface != nullptr) {
279  pOldInterface->Release();
280  }
281  }
282 
283  return *this;
284  }
285 
286  // Copies and AddRef()'s the interface.
287  //
288  _com_ptr_t& operator=(const _com_ptr_t& cp) throw()
289  {
290  return operator=(cp.m_pInterface);
291  }
292 
293  // Moves the interface.
294  //
296  {
297  if (m_pInterface != cp.m_pInterface) {
298  Interface* pOldInterface = m_pInterface;
299 
300  m_pInterface = cp.m_pInterface;
301  cp.m_pInterface = nullptr;
302 
303  if (pOldInterface != nullptr) {
304  pOldInterface->Release();
305  }
306  }
307 
308  return *this;
309  }
310 
311  // This operator is provided to permit the assignment of NULL to the class.
312  // It will issue an error if any value other than NULL is assigned to it.
313  //
315  {
316  if (null != 0) {
317  _com_issue_error(E_POINTER);
318  }
319 
320  return operator=(reinterpret_cast<Interface*>(NULL));
321  }
322 
323  // Construct a pointer for a _variant_t object.
324  //
326  {
327  HRESULT hr = QueryStdInterfaces(varSrc);
328 
329  if (FAILED(hr) && (hr != E_NOINTERFACE)) {
330  _com_issue_error(hr);
331  }
332 
333  return *this;
334  }
335 
336  // If we still have an interface then Release() it. The interface
337  // may be NULL if Detach() has previously been called, or if it was
338  // never set.
339  //
340  ~_com_ptr_t() throw()
341  {
342  _Release();
343  }
344 
345  // Saves/sets the interface without AddRef()ing. This call
346  // will release any previously acquired interface.
347  //
348  void Attach(Interface* pInterface) throw()
349  {
350  _Release();
351  m_pInterface = pInterface;
352  }
353 
354  // Saves/sets the interface only AddRef()ing if fAddRef is TRUE.
355  // This call will release any previously acquired interface.
356  //
357  void Attach(Interface* pInterface, bool fAddRef) throw()
358  {
359  _Release();
360  m_pInterface = pInterface;
361 
362  if (fAddRef) {
363  if (pInterface == NULL) {
364  _com_issue_error(E_POINTER);
365  }
366  else {
367  pInterface->AddRef();
368  }
369  }
370  }
371 
372  // Simply NULL the interface pointer so that it isn't Released()'ed.
373  //
374  Interface* Detach() throw()
375  {
376  Interface* const old = m_pInterface;
377  m_pInterface = NULL;
378  return old;
379  }
380 
381  // Return the interface. This value may be NULL.
382  //
383  operator Interface*() const throw()
384  {
385  return m_pInterface;
386  }
387 
388  // Queries for the unknown and return it
389  // Provides minimal level error checking before use.
390  //
391  operator Interface&() const
392  {
393  if (m_pInterface == NULL) {
394  _com_issue_error(E_POINTER);
395  }
396 
397  return *m_pInterface;
398  }
399 
400  // Allows an instance of this class to act as though it were the
401  // actual interface. Also provides minimal error checking.
402  //
403  Interface& operator*() const
404  {
405  if (m_pInterface == NULL) {
406  _com_issue_error(E_POINTER);
407  }
408 
409  return *m_pInterface;
410  }
411 
412  // Returns the address of the interface pointer contained in this
413  // class. This is useful when using the COM/OLE interfaces to create
414  // this interface.
415  //
416  Interface** operator&() throw()
417  {
418  _Release();
419  m_pInterface = NULL;
420  return &m_pInterface;
421  }
422 
423  // Allows this class to be used as the interface itself.
424  // Also provides simple error checking.
425  //
426  Interface* operator->() const
427  {
428  if (m_pInterface == NULL) {
429  _com_issue_error(E_POINTER);
430  }
431 
432  return m_pInterface;
433  }
434 
435  // This operator is provided so that simple boolean expressions will
436  // work. For example: "if (p) ...".
437  // Returns TRUE if the pointer is not NULL.
438  //
439  operator bool() const throw()
440  {
441  return m_pInterface != NULL;
442  }
443 
444  // Compare two smart pointers
445  //
446  template<typename _OtherIID> bool operator==(const _com_ptr_t<_OtherIID>& p) const
447  {
448  return _CompareUnknown(p) == 0;
449  }
450 
451  // Compare two pointers
452  //
453  template<typename _InterfaceType> bool operator==(_InterfaceType* p) const
454  {
455  return _CompareUnknown(p) == 0;
456  }
457 
458  // Compare with other interface
459  //
460  template<> bool operator==(Interface* p) const
461  {
462  return (m_pInterface == p)
463  ? true
464  : _CompareUnknown(p) == 0;
465  }
466 
467  // Compare two smart pointers
468  //
469  template<> bool operator==(const _com_ptr_t& p) const throw()
470  {
471  return operator==(p.m_pInterface);
472  }
473 
474  // For comparison to NULL
475  //
476  bool operator==(int null) const
477  {
478  if (null != 0) {
479  _com_issue_error(E_POINTER);
480  }
481 
482  return m_pInterface == NULL;
483  }
484 
485  // Compare two smart pointers
486  //
487  template<typename _OtherIID> bool operator!=(const _com_ptr_t<_OtherIID>& p) const
488  {
489  return !(operator==(p));
490  }
491 
492  // Compare two pointers
493  //
494  template<typename _InterfaceType> bool operator!=(_InterfaceType* p) const
495  {
496  return !(operator==(p));
497  }
498 
499  // For comparison to NULL
500  //
501  bool operator!=(int null) const
502  {
503  return !(operator==(null));
504  }
505 
506  // Compare two smart pointers
507  //
508  template<typename _OtherIID> bool operator<(const _com_ptr_t<_OtherIID>& p) const
509  {
510  return _CompareUnknown(p) < 0;
511  }
512 
513  // Compare two pointers
514  //
515  template<typename _InterfaceType> bool operator<(_InterfaceType* p) const
516  {
517  return _CompareUnknown(p) < 0;
518  }
519 
520  // Compare two smart pointers
521  //
522  template<typename _OtherIID> bool operator>(const _com_ptr_t<_OtherIID>& p) const
523  {
524  return _CompareUnknown(p) > 0;
525  }
526 
527  // Compare two pointers
528  //
529  template<typename _InterfaceType> bool operator>(_InterfaceType* p) const
530  {
531  return _CompareUnknown(p) > 0;
532  }
533 
534  // Compare two smart pointers
535  //
536  template<typename _OtherIID> bool operator<=(const _com_ptr_t<_OtherIID>& p) const
537  {
538  return _CompareUnknown(p) <= 0;
539  }
540 
541  // Compare two pointers
542  //
543  template<typename _InterfaceType> bool operator<=(_InterfaceType* p) const
544  {
545  return _CompareUnknown(p) <= 0;
546  }
547 
548  // Compare two smart pointers
549  //
550  template<typename _OtherIID> bool operator>=(const _com_ptr_t<_OtherIID>& p) const
551  {
552  return _CompareUnknown(p) >= 0;
553  }
554 
555  // Compare two pointers
556  //
557  template<typename _InterfaceType> bool operator>=(_InterfaceType* p) const
558  {
559  return _CompareUnknown(p) >= 0;
560  }
561 
562  // Provides error-checking Release()ing of this interface.
563  //
564  void Release()
565  {
566  if (m_pInterface == NULL) {
567  _com_issue_error(E_POINTER);
568  }
569  else {
570  m_pInterface->Release();
571  m_pInterface = NULL;
572  }
573  }
574 
575  // Provides error-checking AddRef()ing of this interface.
576  //
577  void AddRef()
578  {
579  if (m_pInterface == NULL) {
580  _com_issue_error(E_POINTER);
581  }
582  else {
583  m_pInterface->AddRef();
584  }
585  }
586 
587  // Another way to get the interface pointer without casting.
588  //
589  Interface* GetInterfacePtr() const throw()
590  {
591  return m_pInterface;
592  }
593 
594  // Another way to get the interface pointer without casting.
595  // Use for [in, out] parameter passing
596  Interface*& GetInterfacePtr() throw()
597  {
598  return m_pInterface;
599  }
600 
601  // Loads an interface for the provided CLSID.
602  // Returns an HRESULT. Any previous interface is unconditionally released.
603  //
604  HRESULT CreateInstance(const CLSID& rclsid, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
605  {
606  HRESULT hr;
607 
608  _Release();
609 
610  if (dwClsContext & (CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)) {
611  IUnknown* pIUnknown;
612  hr = CoCreateInstance(rclsid, pOuter, dwClsContext, __uuidof(IUnknown), reinterpret_cast<void**>(&pIUnknown));
613 
614  if (SUCCEEDED(hr)) {
615  hr = OleRun(pIUnknown);
616 
617  if (SUCCEEDED(hr)) {
618  hr = pIUnknown->QueryInterface(GetIID(), reinterpret_cast<void**>(&m_pInterface));
619  }
620 
621  pIUnknown->Release();
622  }
623  }
624  else {
625  hr = CoCreateInstance(rclsid, pOuter, dwClsContext, GetIID(), reinterpret_cast<void**>(&m_pInterface));
626  }
627 
628  if (FAILED(hr)) {
629  // just in case refcount = 0 and dtor gets called
630  m_pInterface = NULL;
631  }
632 
633  return hr;
634  }
635 
636  // Creates the class specified by clsidString. clsidString may
637  // contain a class id, or a prog id string.
638  //
639  HRESULT CreateInstance(LPCWSTR clsidString, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
640  {
641  if (clsidString == NULL) {
642  return E_INVALIDARG;
643  }
644 
645  CLSID clsid;
646  HRESULT hr;
647 
648  if (clsidString[0] == L'{') {
649  hr = CLSIDFromString(const_cast<LPWSTR> (clsidString), &clsid);
650  }
651  else {
652  hr = CLSIDFromProgID(const_cast<LPWSTR> (clsidString), &clsid);
653  }
654 
655  if (FAILED(hr)) {
656  return hr;
657  }
658 
659  return CreateInstance(clsid, pOuter, dwClsContext);
660  }
661 
662  // Creates the class specified by SBCS clsidString. clsidString may
663  // contain a class id, or a prog id string.
664  //
665  HRESULT CreateInstance(LPCSTR clsidStringA, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
666  {
667  if (clsidStringA == NULL) {
668  return E_INVALIDARG;
669  }
670 
671  size_t const size = strlen(clsidStringA) + 1;
672 
673  if (size > INT_MAX) {
674  return E_INVALIDARG;
675  }
676 
677  int const destSize = MultiByteToWideChar(CP_ACP, 0, clsidStringA, static_cast<int>(size), NULL, 0);
678 
679  if (destSize == 0) {
680  return HRESULT_FROM_WIN32(GetLastError());
681  }
682 
683  LPWSTR clsidStringW;
684  clsidStringW = static_cast<LPWSTR>(_malloca(destSize * sizeof(WCHAR)));
685 
686  if (clsidStringW == NULL) {
687  return E_OUTOFMEMORY;
688  }
689 
690  if (MultiByteToWideChar(CP_ACP, 0, clsidStringA, static_cast<int>(size), clsidStringW, destSize) == 0) {
691  _freea(clsidStringW);
692  return HRESULT_FROM_WIN32(GetLastError());
693  }
694 
695  HRESULT hr=CreateInstance(clsidStringW, pOuter, dwClsContext);
696  _freea(clsidStringW);
697  return hr;
698  }
699 
700  // Attach to the active object specified by rclsid.
701  // Any previous interface is released.
702  //
703  HRESULT GetActiveObject(const CLSID& rclsid) throw()
704  {
705  _Release();
706 
707  IUnknown* pIUnknown;
708 
709  HRESULT hr = ::GetActiveObject(rclsid, NULL, &pIUnknown);
710 
711  if (SUCCEEDED(hr)) {
712  hr = pIUnknown->QueryInterface(GetIID(), reinterpret_cast<void**>(&m_pInterface));
713 
714  pIUnknown->Release();
715  }
716 
717  if (FAILED(hr)) {
718  // just in case refcount = 0 and dtor gets called
719  m_pInterface = NULL;
720  }
721 
722  return hr;
723  }
724 
725  // Attach to the active object specified by clsidString.
726  // First convert the LPCWSTR to a CLSID.
727  //
728  HRESULT GetActiveObject(LPCWSTR clsidString) throw()
729  {
730  if (clsidString == NULL) {
731  return E_INVALIDARG;
732  }
733 
734  CLSID clsid;
735  HRESULT hr;
736 
737  if (clsidString[0] == '{') {
738  hr = CLSIDFromString(const_cast<LPWSTR> (clsidString), &clsid);
739  }
740  else {
741  hr = CLSIDFromProgID(const_cast<LPWSTR> (clsidString), &clsid);
742  }
743 
744  if (FAILED(hr)) {
745  return hr;
746  }
747 
748  return GetActiveObject(clsid);
749  }
750 
751  // Attach to the active object specified by clsidStringA.
752  // First convert the LPCSTR to a LPCWSTR.
753  //
754  HRESULT GetActiveObject(LPCSTR clsidStringA) throw()
755  {
756  if (clsidStringA == NULL) {
757  return E_INVALIDARG;
758  }
759 
760  size_t const size = strlen(clsidStringA) + 1;
761 
762  if (size > INT_MAX) {
763  return E_INVALIDARG;
764  }
765 
766  int const destSize = MultiByteToWideChar(CP_ACP, 0, clsidStringA, static_cast<int>(size), NULL, 0);
767 
768  LPWSTR clsidStringW;
769  __try {
770  clsidStringW = static_cast<LPWSTR>(_alloca(destSize * sizeof(WCHAR)));
771  }
772  __except (GetExceptionCode() == STATUS_STACK_OVERFLOW) {
773  clsidStringW = NULL;
774  }
775 
776  if (clsidStringW == NULL) {
777  return E_OUTOFMEMORY;
778  }
779 
780  if (MultiByteToWideChar(CP_ACP, 0, clsidStringA, static_cast<int>(size), clsidStringW, destSize) == 0) {
781  return HRESULT_FROM_WIN32(GetLastError());
782  }
783 
784  return GetActiveObject(clsidStringW);
785  }
786 
787  // Performs the QI for the specified IID and returns it in p.
788  // As with all QIs, the interface will be AddRef'd.
789  //
790  template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType*& p) throw ()
791  {
792  if (m_pInterface != NULL) {
793  return m_pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p));
794  }
795 
796  return E_POINTER;
797  }
798 
799  // Performs the QI for the specified IID and returns it in p.
800  // As with all QIs, the interface will be AddRef'd.
801  //
802  template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType** p) throw()
803  {
804  return QueryInterface(iid, *p);
805  }
806 
807 private:
808  // The Interface.
809  //
810  Interface* m_pInterface;
811 
812  // Releases only if the interface is not null.
813  // The interface is not set to NULL.
814  //
815  void _Release() throw()
816  {
817  if (m_pInterface != NULL) {
818  m_pInterface->Release();
819  }
820  }
821 
822  // AddRefs only if the interface is not NULL
823  //
824  void _AddRef() throw()
825  {
826  if (m_pInterface != NULL) {
827  m_pInterface->AddRef();
828  }
829  }
830 
831  // Performs a QI on pUnknown for the interface type returned
832  // for this class. The interface is stored. If pUnknown is
833  // NULL, or the QI fails, E_NOINTERFACE is returned and
834  // _pInterface is set to NULL.
835  //
836  template<typename _InterfacePtr> HRESULT _QueryInterface(_InterfacePtr p) throw()
837  {
838  HRESULT hr;
839 
840  // Can't QI NULL
841  //
842  if (p != NULL) {
843  // Query for this interface
844  //
845  Interface* pInterface = NULL;
846  hr = p->QueryInterface(GetIID(), reinterpret_cast<void**>(&pInterface));
847 
848  // Save the interface without AddRef()ing.
849  //
850  Attach(SUCCEEDED(hr)? pInterface: NULL);
851  }
852  else {
853  operator=(static_cast<Interface*>(NULL));
854  hr = E_NOINTERFACE;
855  }
856 
857  return hr;
858  }
859 
860  // Compares the provided pointer with this by obtaining IUnknown interfaces
861  // for each pointer and then returning the difference.
862  //
863  template<typename _InterfacePtr> int _CompareUnknown(_InterfacePtr p) const
864  {
865  IUnknown* pu1 = NULL;
866  IUnknown* pu2 = NULL;
867 
868  if (m_pInterface != NULL) {
869  HRESULT hr = m_pInterface->QueryInterface(__uuidof(IUnknown), reinterpret_cast<void**>(&pu1));
870 
871  if (FAILED(hr)) {
872  pu1 = NULL;
873  _com_issue_error(hr);
874  }
875  else {
876  pu1->Release();
877  }
878  }
879 
880  if (p != NULL) {
881  HRESULT hr = p->QueryInterface(__uuidof(IUnknown), reinterpret_cast<void**>(&pu2));
882 
883  if (FAILED(hr)) {
884  pu2 = NULL;
885  _com_issue_error(hr);
886  }
887  else {
888  pu2->Release();
889  }
890  }
891 
892  if (pu1 == pu2)
893  {
894  return 0;
895  }
896 
897  return (pu1 > pu2) ? 1 : -1;
898  }
899 
900  // Try to extract either IDispatch* or an IUnknown* from
901  // the VARIANT
902  //
903  HRESULT QueryStdInterfaces(const _variant_t& varSrc) throw()
904  {
905  if (V_VT(&varSrc) == VT_DISPATCH) {
906  return _QueryInterface(V_DISPATCH(&varSrc));
907  }
908 
909  if (V_VT(&varSrc) == VT_UNKNOWN) {
910  return _QueryInterface(V_UNKNOWN(&varSrc));
911  }
912 
913  // We have something other than an IUnknown or an IDispatch.
914  // Can we convert it to either one of these?
915  // Try IDispatch first
916  //
917  VARIANT varDest;
918  VariantInit(&varDest);
919 
920  HRESULT hr = VariantChangeType(&varDest, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)), 0, VT_DISPATCH);
921  if (SUCCEEDED(hr)) {
922  hr = _QueryInterface(V_DISPATCH(&varDest));
923  }
924 
925  if (hr == E_NOINTERFACE) {
926  // That failed ... so try IUnknown
927  //
928  VariantInit(&varDest);
929  hr = VariantChangeType(&varDest, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)), 0, VT_UNKNOWN);
930  if (SUCCEEDED(hr)) {
931  hr = _QueryInterface(V_UNKNOWN(&varDest));
932  }
933  }
934 
935  VariantClear(&varDest);
936  return hr;
937  }
938 };
939 
940 // Reverse comparison operators for _com_ptr_t
941 //
942 template<typename _InterfaceType> bool operator==(int null, const _com_ptr_t<_InterfaceType>& p)
943 {
944  if (null != 0) {
945  _com_issue_error(E_POINTER);
946  }
947 
948  return p == NULL;
949 }
950 
951 template<typename _Interface, typename _InterfacePtr> bool operator==(_Interface* i, const _com_ptr_t<_InterfacePtr>& p)
952 {
953  return p == i;
954 }
955 
956 template<typename _Interface> bool operator!=(int null, const _com_ptr_t<_Interface>& p)
957 {
958  if (null != 0) {
959  _com_issue_error(E_POINTER);
960  }
961 
962  return p != NULL;
963 }
964 
965 template<typename _Interface, typename _InterfacePtr> bool operator!=(_Interface* i, const _com_ptr_t<_InterfacePtr>& p)
966 {
967  return p != i;
968 }
969 
970 template<typename _Interface> bool operator<(int null, const _com_ptr_t<_Interface>& p)
971 {
972  if (null != 0) {
973  _com_issue_error(E_POINTER);
974  }
975 
976  return p > NULL;
977 }
978 
979 template<typename _Interface, typename _InterfacePtr> bool operator<(_Interface* i, const _com_ptr_t<_InterfacePtr>& p)
980 {
981  return p > i;
982 }
983 
984 template<typename _Interface> bool operator>(int null, const _com_ptr_t<_Interface>& p)
985 {
986  if (null != 0) {
987  _com_issue_error(E_POINTER);
988  }
989 
990  return p < NULL;
991 }
992 
993 template<typename _Interface, typename _InterfacePtr> bool operator>(_Interface* i, const _com_ptr_t<_InterfacePtr>& p)
994 {
995  return p < i;
996 }
997 
998 template<typename _Interface> bool operator<=(int null, const _com_ptr_t<_Interface>& p)
999 {
1000  if (null != 0) {
1001  _com_issue_error(E_POINTER);
1002  }
1003 
1004  return p >= NULL;
1005 }
1006 
1007 template<typename _Interface, typename _InterfacePtr> bool operator<=(_Interface* i, const _com_ptr_t<_InterfacePtr>& p)
1008 {
1009  return p >= i;
1010 }
1011 
1012 template<typename _Interface> bool operator>=(int null, const _com_ptr_t<_Interface>& p)
1013 {
1014  if (null != 0) {
1015  _com_issue_error(E_POINTER);
1016  }
1017 
1018  return p <= NULL;
1019 }
1020 
1021 template<typename _Interface, typename _InterfacePtr> bool operator>=(_Interface* i, const _com_ptr_t<_InterfacePtr>& p)
1022 {
1023  return p <= i;
1024 }
1025 
1026 #pragma pop_macro("new")
1027 #pragma warning(pop)
1028 
1029 #endif // _INC_COMIP
bool operator==(_InterfaceType *p) const
Definition: comip.h:453
Definition: comdef.h:247
Definition: comip.h:60
void _AddRef()
Definition: comip.h:824
Interface & operator*() const
Definition: comip.h:403
#define NULL
Definition: vcruntime.h:236
bool operator>(const _com_ptr_t< _OtherIID > &p) const
Definition: comip.h:522
bool operator!=(int null, const _com_ptr_t< _Interface > &p)
Definition: comip.h:956
bool operator==(int null, const _com_ptr_t< _InterfaceType > &p)
Definition: comip.h:942
_com_ptr_t(const _com_ptr_t &cp)
Definition: comip.h:158
constexpr auto size(const _Container &_Cont) -> decltype(_Cont.size())
Definition: xutility:1478
HRESULT CreateInstance(LPCSTR clsidStringA, IUnknown *pOuter=NULL, DWORD dwClsContext=CLSCTX_ALL)
Definition: comip.h:665
int _CompareUnknown(_InterfacePtr p) const
Definition: comip.h:863
_com_ptr_t & operator=(const _variant_t &varSrc)
Definition: comip.h:325
Interface * operator->() const
Definition: comip.h:426
Interface *& GetInterfacePtr()
Definition: comip.h:596
bool operator>=(int null, const _com_ptr_t< _Interface > &p)
Definition: comip.h:1012
HRESULT _QueryInterface(_InterfacePtr p)
Definition: comip.h:836
static _Interface * GetInterfacePtr()
Definition: comip.h:44
void _Release()
Definition: comip.h:815
void __stdcall _com_issue_error(HRESULT)
_com_ptr_t(const _variant_t &varSrc)
Definition: comip.h:193
bool operator==(const _com_ptr_t< _OtherIID > &p) const
Definition: comip.h:446
_com_ptr_t()
Definition: comip.h:133
_com_ptr_t(LPCSTR str, IUnknown *pOuter=NULL, DWORD dwClsContext=CLSCTX_ALL)
Definition: comip.h:231
_com_ptr_t(_com_ptr_t &&cp)
Definition: comip.h:166
_com_ptr_t(LPCWSTR str, IUnknown *pOuter=NULL, DWORD dwClsContext=CLSCTX_ALL)
Definition: comip.h:218
bool operator!=(int null) const
Definition: comip.h:501
Definition: comutil.h:1002
HRESULT QueryStdInterfaces(const _variant_t &varSrc)
Definition: comip.h:903
_com_ptr_t(Interface *pInterface)
Definition: comip.h:174
bool operator<=(_InterfaceType *p) const
Definition: comip.h:543
struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown
HRESULT CreateInstance(const CLSID &rclsid, IUnknown *pOuter=NULL, DWORD dwClsContext=CLSCTX_ALL)
Definition: comip.h:604
_com_ptr_t(_In_ LPSTR str)
Definition: comip.h:104
int i[4]
Definition: dvec.h:68
#define _In_
Definition: sal.h:305
Interface * GetInterfacePtr() const
Definition: comip.h:589
#define FAILED(hr)
Definition: comutil.h:71
bool operator>=(_InterfaceType *p) const
Definition: comip.h:557
#define bool
Definition: stdbool.h:15
_com_ptr_t & operator=(Interface *pInterface)
Definition: comip.h:269
~_com_ptr_t()
Definition: comip.h:340
bool operator==(const _com_ptr_t &p) const
Definition: comip.h:469
_com_ptr_t(Interface *pInterface, bool fAddRef)
Definition: comip.h:183
_com_ptr_t & operator=(int null)
Definition: comip.h:314
bool operator==(Interface *p) const
Definition: comip.h:460
Interface * Detach()
Definition: comip.h:374
_com_ptr_t(int null)
Definition: comip.h:141
bool operator!=(_InterfaceType *p) const
Definition: comip.h:494
HRESULT CreateInstance(LPCWSTR clsidString, IUnknown *pOuter=NULL, DWORD dwClsContext=CLSCTX_ALL)
Definition: comip.h:639
unsigned long DWORD
Definition: concrt.h:63
_com_ptr_t(_In_ LPWSTR str)
Definition: comip.h:111
Interface ** operator&()
Definition: comip.h:416
_com_ptr_t(_InterfaceType *p)
Definition: comip.h:92
#define GetExceptionCode
Definition: excpt.h:62
void Attach(Interface *pInterface, bool fAddRef)
Definition: comip.h:357
void Release()
Definition: comip.h:564
bool operator>=(const _com_ptr_t< _OtherIID > &p) const
Definition: comip.h:550
bool operator<(_InterfaceType *p) const
Definition: comip.h:515
_com_ptr_t & operator=(const _com_ptr_t &cp)
Definition: comip.h:288
static const IID & GetIID()
Definition: comip.h:54
void Attach(Interface *pInterface)
Definition: comip.h:348
_com_ptr_t & operator=(_com_ptr_t &&cp)
Definition: comip.h:295
HRESULT GetActiveObject(const CLSID &rclsid)
Definition: comip.h:703
HRESULT QueryInterface(const IID &iid, _InterfaceType *&p)
Definition: comip.h:790
_com_ptr_t & operator=(_InterfaceType *p)
Definition: comip.h:256
_com_ptr_t & operator=(const _com_ptr_t< _OtherIID > &p)
Definition: comip.h:243
HRESULT QueryInterface(const IID &iid, _InterfaceType **p)
Definition: comip.h:802
HRESULT GetActiveObject(LPCSTR clsidStringA)
Definition: comip.h:754
Interface * m_pInterface
Definition: comip.h:810
static _Interface & GetInterface()
Definition: comip.h:49
_IIID ThisIIID
Definition: comip.h:65
Definition: comip.h:40
bool operator>(int null, const _com_ptr_t< _Interface > &p)
Definition: comip.h:984
bool operator==(int null) const
Definition: comip.h:476
#define INT_MAX
Definition: limits.h:35
bool operator>(_InterfaceType *p) const
Definition: comip.h:529
_com_ptr_t(const _com_ptr_t< _OtherIID > &p)
Definition: comip.h:80
_Interface Interface
Definition: comip.h:42
HRESULT GetActiveObject(LPCWSTR clsidString)
Definition: comip.h:728
_com_ptr_t(const CLSID &clsid, IUnknown *pOuter=NULL, DWORD dwClsContext=CLSCTX_ALL)
Definition: comip.h:205
_com_ptr_t(_com_ptr_t *p)
Definition: comip.h:119
static const IID & GetIID()
Definition: comip.h:73
void AddRef()
Definition: comip.h:577
_IIID::Interface Interface
Definition: comip.h:66
bool operator!=(const _com_ptr_t< _OtherIID > &p) const
Definition: comip.h:487