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