Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

879 lines
19 KiB

  1. /***
  2. * comip.h - Native C++ compiler COM support - COM interface pointers header
  3. *
  4. * Copyright (C) 1996-1999 Microsoft Corporation
  5. * All rights reserved.
  6. *
  7. ****/
  8. #if !defined(_INC_COMIP)
  9. #define _INC_COMIP
  10. #if _MSC_VER > 1000
  11. #pragma once
  12. #endif
  13. #include <ole2.h>
  14. #include <malloc.h>
  15. #include <comutil.h>
  16. #if _MSC_VER >= 1200
  17. #pragma warning(push)
  18. #endif
  19. #pragma warning(disable: 4290)
  20. class _com_error;
  21. void __stdcall _com_issue_error(HRESULT);
  22. struct __declspec(uuid("00000000-0000-0000-c000-000000000046")) IUnknown;
  23. // Provide Interface to IID association
  24. //
  25. template<typename _Interface, const IID* _IID /*= &__uuidof(_Interface)*/> class _com_IIID {
  26. public:
  27. typedef _Interface Interface;
  28. static _Interface* GetInterfacePtr() throw()
  29. {
  30. return NULL;
  31. }
  32. static _Interface& GetInterface() throw()
  33. {
  34. return *GetInterfacePtr();
  35. }
  36. static const IID& GetIID() throw()
  37. {
  38. return *_IID;
  39. }
  40. };
  41. template<typename _IIID> class _com_ptr_t {
  42. public:
  43. // Declare interface type so that the type may be available outside
  44. // the scope of this template.
  45. //
  46. typedef _IIID ThisIIID;
  47. typedef typename _IIID::Interface Interface;
  48. // When the compiler supports references in template parameters,
  49. // _CLSID will be changed to a reference. To avoid conversion
  50. // difficulties this function should be used to obtain the
  51. // CLSID.
  52. //
  53. static const IID& GetIID() throw()
  54. {
  55. return ThisIIID::GetIID();
  56. }
  57. // Constructs a smart-pointer from any interface pointer.
  58. //
  59. template<typename _InterfacePtr> _com_ptr_t(const _InterfacePtr& p) throw(_com_error)
  60. : m_pInterface(NULL)
  61. {
  62. if (p) {
  63. HRESULT hr = _QueryInterface(p);
  64. if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  65. _com_issue_error(hr);
  66. }
  67. }
  68. }
  69. // Disable conversion using _com_ptr_t* specialization of
  70. // template<typename _InterfacePtr> _com_ptr_t(const _InterfacePtr& p)
  71. template<> explicit _com_ptr_t(_com_ptr_t* const & p) throw(_com_error)
  72. {
  73. if (p != NULL) {
  74. _com_issue_error(E_POINTER);
  75. }
  76. else {
  77. m_pInterface = p->m_pInterface;
  78. AddRef();
  79. }
  80. }
  81. // Default constructor.
  82. //
  83. _com_ptr_t() throw()
  84. : m_pInterface(NULL)
  85. {
  86. }
  87. // This constructor is provided to allow NULL assignment. It will issue
  88. // an error if any value other than null is assigned to the object.
  89. //
  90. _com_ptr_t(int null) throw(_com_error)
  91. : m_pInterface(NULL)
  92. {
  93. if (null != 0) {
  94. _com_issue_error(E_POINTER);
  95. }
  96. }
  97. // Copy the pointer and AddRef().
  98. //
  99. template<> _com_ptr_t(const _com_ptr_t& cp) throw()
  100. : m_pInterface(cp.m_pInterface)
  101. {
  102. _AddRef();
  103. }
  104. // Saves the interface.
  105. //
  106. _com_ptr_t(Interface* pInterface) throw()
  107. : m_pInterface(pInterface)
  108. {
  109. _AddRef();
  110. }
  111. // Copies the pointer. If fAddRef is TRUE, the interface will
  112. // be AddRef()ed.
  113. //
  114. _com_ptr_t(Interface* pInterface, bool fAddRef) throw()
  115. : m_pInterface(pInterface)
  116. {
  117. if (fAddRef) {
  118. _AddRef();
  119. }
  120. }
  121. // Construct a pointer for a _variant_t object.
  122. //
  123. template<> _com_ptr_t(const _variant_t& varSrc) throw(_com_error)
  124. : m_pInterface(NULL)
  125. {
  126. HRESULT hr = QueryStdInterfaces(varSrc);
  127. if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  128. _com_issue_error(hr);
  129. }
  130. }
  131. // Calls CoCreateClass with the provided CLSID.
  132. //
  133. explicit _com_ptr_t(const CLSID& clsid, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw(_com_error)
  134. : m_pInterface(NULL)
  135. {
  136. HRESULT hr = CreateInstance(clsid, pOuter, dwClsContext);
  137. if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  138. _com_issue_error(hr);
  139. }
  140. }
  141. // Calls CoCreateClass with the provided CLSID retrieved from
  142. // the string.
  143. //
  144. explicit _com_ptr_t(LPOLESTR str, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw(_com_error)
  145. : m_pInterface(NULL)
  146. {
  147. HRESULT hr = CreateInstance(str, pOuter, dwClsContext);
  148. if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  149. _com_issue_error(hr);
  150. }
  151. }
  152. // Calls CoCreateClass with the provided SBCS CLSID retrieved from
  153. // the string.
  154. //
  155. explicit _com_ptr_t(LPCSTR str, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw(_com_error)
  156. : m_pInterface(NULL)
  157. {
  158. HRESULT hr = CreateInstance(str, pOuter, dwClsContext);
  159. if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  160. _com_issue_error(hr);
  161. }
  162. }
  163. // Queries for interface.
  164. //
  165. template<typename _InterfacePtr> _com_ptr_t& operator=(const _InterfacePtr& p) throw(_com_error)
  166. {
  167. HRESULT hr = _QueryInterface(p);
  168. if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  169. _com_issue_error(hr);
  170. }
  171. return *this;
  172. }
  173. // Saves the interface.
  174. //
  175. _com_ptr_t& operator=(Interface* pInterface) throw()
  176. {
  177. if (m_pInterface != pInterface) {
  178. Interface* pOldInterface = m_pInterface;
  179. m_pInterface = pInterface;
  180. _AddRef();
  181. if (pOldInterface != NULL) {
  182. pOldInterface->Release();
  183. }
  184. }
  185. return *this;
  186. }
  187. // Copies and AddRef()'s the interface.
  188. //
  189. template<> _com_ptr_t& operator=(const _com_ptr_t& cp) throw()
  190. {
  191. return operator=(cp.m_pInterface);
  192. }
  193. // This operator is provided to permit the assignment of NULL to the class.
  194. // It will issue an error if any value other than NULL is assigned to it.
  195. //
  196. _com_ptr_t& operator=(int null) throw(_com_error)
  197. {
  198. if (null != 0) {
  199. _com_issue_error(E_POINTER);
  200. }
  201. return operator=(reinterpret_cast<Interface*>(NULL));
  202. }
  203. // Construct a pointer for a _variant_t object.
  204. //
  205. template<> _com_ptr_t& operator=(const _variant_t& varSrc) throw(_com_error)
  206. {
  207. HRESULT hr = QueryStdInterfaces(varSrc);
  208. if (FAILED(hr) && (hr != E_NOINTERFACE)) {
  209. _com_issue_error(hr);
  210. }
  211. return *this;
  212. }
  213. // If we still have an interface then Release() it. The interface
  214. // may be NULL if Detach() has previously been called, or if it was
  215. // never set.
  216. //
  217. ~_com_ptr_t() throw()
  218. {
  219. _Release();
  220. }
  221. // Saves/sets the interface without AddRef()ing. This call
  222. // will release any previously acquired interface.
  223. //
  224. void Attach(Interface* pInterface) throw()
  225. {
  226. _Release();
  227. m_pInterface = pInterface;
  228. }
  229. // Saves/sets the interface only AddRef()ing if fAddRef is TRUE.
  230. // This call will release any previously acquired interface.
  231. //
  232. void Attach(Interface* pInterface, bool fAddRef) throw()
  233. {
  234. _Release();
  235. m_pInterface = pInterface;
  236. if (fAddRef) {
  237. if (pInterface != NULL) {
  238. pInterface->AddRef();
  239. }
  240. }
  241. }
  242. // Simply NULL the interface pointer so that it isn't Released()'ed.
  243. //
  244. Interface* Detach() throw()
  245. {
  246. Interface* const old=m_pInterface;
  247. m_pInterface = NULL;
  248. return old;
  249. }
  250. // Return the interface. This value may be NULL.
  251. //
  252. operator Interface*() const throw()
  253. {
  254. return m_pInterface;
  255. }
  256. // Queries for the unknown and return it
  257. // Provides minimal level error checking before use.
  258. //
  259. operator Interface&() const throw(_com_error)
  260. {
  261. if (m_pInterface == NULL) {
  262. _com_issue_error(E_POINTER);
  263. }
  264. return *m_pInterface;
  265. }
  266. // Allows an instance of this class to act as though it were the
  267. // actual interface. Also provides minimal error checking.
  268. //
  269. Interface& operator*() const throw(_com_error)
  270. {
  271. if (m_pInterface == NULL) {
  272. _com_issue_error(E_POINTER);
  273. }
  274. return *m_pInterface;
  275. }
  276. // Returns the address of the interface pointer contained in this
  277. // class. This is useful when using the COM/OLE interfaces to create
  278. // this interface.
  279. //
  280. Interface** operator&() throw()
  281. {
  282. _Release();
  283. m_pInterface = NULL;
  284. return &m_pInterface;
  285. }
  286. // Allows this class to be used as the interface itself.
  287. // Also provides simple error checking.
  288. //
  289. Interface* operator->() const throw(_com_error)
  290. {
  291. if (m_pInterface == NULL) {
  292. _com_issue_error(E_POINTER);
  293. }
  294. return m_pInterface;
  295. }
  296. // This operator is provided so that simple boolean expressions will
  297. // work. For example: "if (p) ...".
  298. // Returns TRUE if the pointer is not NULL.
  299. //
  300. operator bool() const throw()
  301. {
  302. return m_pInterface != NULL;
  303. }
  304. // Compare two pointers
  305. //
  306. template<typename _InterfacePtr> bool operator==(_InterfacePtr p) throw(_com_error)
  307. {
  308. return _CompareUnknown(p) == 0;
  309. }
  310. // Compare with other interface
  311. //
  312. template<> bool operator==(Interface* p) throw(_com_error)
  313. {
  314. return (m_pInterface == p) ? true : _CompareUnknown(p) == 0;
  315. }
  316. // Compares 2 _com_ptr_t's
  317. //
  318. template<> bool operator==(_com_ptr_t& p) throw()
  319. {
  320. return operator==(p.m_pInterface);
  321. }
  322. // For comparison to NULL
  323. //
  324. template<> bool operator==(int null) throw(_com_error)
  325. {
  326. if (null != 0) {
  327. _com_issue_error(E_POINTER);
  328. }
  329. return m_pInterface == NULL;
  330. }
  331. // Compare two pointers
  332. //
  333. template<typename _InterfacePtr> bool operator!=(_InterfacePtr p) throw(_com_error)
  334. {
  335. return !(operator==(p));
  336. }
  337. // Compare with other interface
  338. //
  339. template<> bool operator!=(Interface* p) throw(_com_error)
  340. {
  341. return !(operator==(p));
  342. }
  343. // Compares 2 _com_ptr_t's
  344. //
  345. template<> bool operator!=(_com_ptr_t& p) throw(_com_error)
  346. {
  347. return !(operator==(p));
  348. }
  349. // For comparison to NULL
  350. //
  351. template<> bool operator!=(int null) throw(_com_error)
  352. {
  353. return !(operator==(null));
  354. }
  355. // Compare two pointers
  356. //
  357. template<typename _InterfacePtr> bool operator<(_InterfacePtr p) throw(_com_error)
  358. {
  359. return _CompareUnknown(p) < 0;
  360. }
  361. // Compare two pointers
  362. //
  363. template<typename _InterfacePtr> bool operator>(_InterfacePtr p) throw(_com_error)
  364. {
  365. return _CompareUnknown(p) > 0;
  366. }
  367. // Compare two pointers
  368. //
  369. template<typename _InterfacePtr> bool operator<=(_InterfacePtr p) throw(_com_error)
  370. {
  371. return _CompareUnknown(p) <= 0;
  372. }
  373. // Compare two pointers
  374. //
  375. template<typename _InterfacePtr> bool operator>=(_InterfacePtr p) throw(_com_error)
  376. {
  377. return _CompareUnknown(p) >= 0;
  378. }
  379. // Provides error-checking Release()ing of this interface.
  380. //
  381. void Release() throw(_com_error)
  382. {
  383. if (m_pInterface == NULL) {
  384. _com_issue_error(E_POINTER);
  385. }
  386. m_pInterface->Release();
  387. m_pInterface = NULL;
  388. }
  389. // Provides error-checking AddRef()ing of this interface.
  390. //
  391. void AddRef() throw(_com_error)
  392. {
  393. if (m_pInterface == NULL) {
  394. _com_issue_error(E_POINTER);
  395. }
  396. m_pInterface->AddRef();
  397. }
  398. // Another way to get the interface pointer without casting.
  399. //
  400. Interface* GetInterfacePtr() const throw()
  401. {
  402. return m_pInterface;
  403. }
  404. // Loads an interface for the provided CLSID.
  405. // Returns an HRESULT. Any previous interface is released.
  406. //
  407. HRESULT CreateInstance(const CLSID& rclsid, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
  408. {
  409. HRESULT hr;
  410. _Release();
  411. if (dwClsContext & (CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)) {
  412. IUnknown* pIUnknown;
  413. hr = CoCreateInstance(rclsid, pOuter, dwClsContext, __uuidof(IUnknown), reinterpret_cast<void**>(&pIUnknown));
  414. if (FAILED(hr)) {
  415. return hr;
  416. }
  417. hr = OleRun(pIUnknown);
  418. if (SUCCEEDED(hr)) {
  419. hr = pIUnknown->QueryInterface(GetIID(), reinterpret_cast<void**>(&m_pInterface));
  420. }
  421. pIUnknown->Release();
  422. }
  423. else {
  424. hr = CoCreateInstance(rclsid, pOuter, dwClsContext, GetIID(), reinterpret_cast<void**>(&m_pInterface));
  425. }
  426. return hr;
  427. }
  428. // Creates the class specified by clsidString. clsidString may
  429. // contain a class id, or a prog id string.
  430. //
  431. HRESULT CreateInstance(LPOLESTR clsidString, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
  432. {
  433. if (clsidString == NULL) {
  434. return E_INVALIDARG;
  435. }
  436. CLSID clsid;
  437. HRESULT hr;
  438. if (clsidString[0] == '{') {
  439. hr = CLSIDFromString(clsidString, &clsid);
  440. }
  441. else {
  442. hr = CLSIDFromProgID(clsidString, &clsid);
  443. }
  444. if (FAILED(hr)) {
  445. return hr;
  446. }
  447. return CreateInstance(clsid, pOuter, dwClsContext);
  448. }
  449. // Creates the class specified by SBCS clsidString. clsidString may
  450. // contain a class id, or a prog id string.
  451. //
  452. HRESULT CreateInstance(LPCSTR clsidStringA, IUnknown* pOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
  453. {
  454. if (clsidStringA == NULL) {
  455. return E_INVALIDARG;
  456. }
  457. int size = lstrlenA(clsidStringA) + 1;
  458. LPOLESTR clsidStringW = static_cast<LPOLESTR>(_alloca(size * 2));
  459. clsidStringW[0] = '\0';
  460. if (MultiByteToWideChar(CP_ACP, 0, clsidStringA, -1, clsidStringW, size) == 0) {
  461. return HRESULT_FROM_WIN32(GetLastError());
  462. }
  463. return CreateInstance(clsidStringW, pOuter, dwClsContext);
  464. }
  465. // Attach to the active object specified by rclsid.
  466. // Any previous interface is released.
  467. //
  468. HRESULT GetActiveObject(const CLSID& rclsid) throw()
  469. {
  470. _Release();
  471. IUnknown* pIUnknown;
  472. HRESULT hr = ::GetActiveObject(rclsid, NULL, &pIUnknown);
  473. if (FAILED(hr)) {
  474. return hr;
  475. }
  476. hr = pIUnknown->QueryInterface(GetIID(), reinterpret_cast<void**>(&m_pInterface));
  477. if (FAILED(hr)) {
  478. return hr;
  479. }
  480. pIUnknown->Release();
  481. return hr;
  482. }
  483. // Attach to the active object specified by clsidString.
  484. // First convert the LPOLESTR to a CLSID.
  485. //
  486. HRESULT GetActiveObject(LPOLESTR clsidString) throw()
  487. {
  488. if (clsidString == NULL) {
  489. return E_INVALIDARG;
  490. }
  491. CLSID clsid;
  492. HRESULT hr;
  493. if (clsidString[0] == '{') {
  494. hr = CLSIDFromString(clsidString, &clsid);
  495. }
  496. else {
  497. hr = CLSIDFromProgID(clsidString, &clsid);
  498. }
  499. if (FAILED(hr)) {
  500. return hr;
  501. }
  502. return GetActiveObject(clsid);
  503. }
  504. // Attach to the active object specified by clsidStringA.
  505. // First convert the LPCSTR to a LPOLESTR.
  506. //
  507. HRESULT GetActiveObject(LPCSTR clsidStringA) throw()
  508. {
  509. if (clsidStringA == NULL) {
  510. return E_INVALIDARG;
  511. }
  512. int size = lstrlenA(clsidStringA) + 1;
  513. LPOLESTR clsidStringW = static_cast<LPOLESTR>(_alloca(size * 2));
  514. clsidStringW[0] = '\0';
  515. if (MultiByteToWideChar(CP_ACP, 0, clsidStringA, -1, clsidStringW, size) == 0) {
  516. return HRESULT_FROM_WIN32(GetLastError());
  517. }
  518. return GetActiveObject(clsidStringW);
  519. }
  520. // Performs the QI for the specified IID and returns it in p.
  521. // As with all QIs, the interface will be AddRef'd.
  522. //
  523. template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType*& p) throw ()
  524. {
  525. if (m_pInterface != NULL) {
  526. return m_pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p));
  527. }
  528. return E_POINTER;
  529. }
  530. // Performs the QI for the specified IID and returns it in p.
  531. // As with all QIs, the interface will be AddRef'd.
  532. //
  533. template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType** p) throw()
  534. {
  535. return QueryInterface(iid, *p);
  536. }
  537. private:
  538. // The Interface.
  539. //
  540. Interface* m_pInterface;
  541. // Releases only if the interface is not null.
  542. // The interface is not set to NULL.
  543. //
  544. void _Release() throw()
  545. {
  546. if (m_pInterface != NULL) {
  547. m_pInterface->Release();
  548. }
  549. }
  550. // AddRefs only if the interface is not NULL
  551. //
  552. void _AddRef() throw()
  553. {
  554. if (m_pInterface != NULL) {
  555. m_pInterface->AddRef();
  556. }
  557. }
  558. // Performs a QI on pUnknown for the interface type returned
  559. // for this class. The interface is stored. If pUnknown is
  560. // NULL, or the QI fails, E_NOINTERFACE is returned and
  561. // _pInterface is set to NULL.
  562. //
  563. template<typename _InterfacePtr> HRESULT _QueryInterface(const _InterfacePtr& p) throw()
  564. {
  565. HRESULT hr;
  566. // Can't QI NULL
  567. //
  568. if (p) {
  569. // Query for this interface
  570. //
  571. Interface* pInterface;
  572. hr = p->QueryInterface(GetIID(), reinterpret_cast<void**>(&pInterface));
  573. if (FAILED(hr)) {
  574. // If failed initialize interface to NULL and return HRESULT.
  575. //
  576. Attach(NULL);
  577. return hr;
  578. }
  579. // Save the interface without AddRef()ing.
  580. //
  581. Attach(pInterface);
  582. }
  583. else {
  584. operator=(static_cast<Interface*>(NULL));
  585. hr = E_NOINTERFACE;
  586. }
  587. return hr;
  588. }
  589. // Compares the provided pointer with this by obtaining IUnknown interfaces
  590. // for each pointer and then returning the difference.
  591. //
  592. template<typename _InterfacePtr> int _CompareUnknown(_InterfacePtr p) throw(_com_error)
  593. {
  594. IUnknown* pu1, *pu2;
  595. if (m_pInterface != NULL) {
  596. HRESULT hr = m_pInterface->QueryInterface(__uuidof(IUnknown), reinterpret_cast<void**>(&pu1));
  597. if (FAILED(hr)) {
  598. _com_issue_error(hr);
  599. }
  600. pu1->Release();
  601. }
  602. else {
  603. pu1 = NULL;
  604. }
  605. if (p) {
  606. HRESULT hr = p->QueryInterface(__uuidof(IUnknown), reinterpret_cast<void**>(&pu2));
  607. if (FAILED(hr)) {
  608. _com_issue_error(hr);
  609. }
  610. pu2->Release();
  611. }
  612. else {
  613. pu2 = NULL;
  614. }
  615. return pu1 - pu2;
  616. }
  617. // Try to extract either IDispatch* or an IUnknown* from
  618. // the VARIANT
  619. //
  620. HRESULT QueryStdInterfaces(const _variant_t& varSrc) throw()
  621. {
  622. if (V_VT(&varSrc) == VT_DISPATCH) {
  623. return _QueryInterface(V_DISPATCH(&varSrc));
  624. }
  625. if (V_VT(&varSrc) == VT_UNKNOWN) {
  626. return _QueryInterface(V_UNKNOWN(&varSrc));
  627. }
  628. // We have something other than an IUnknown or an IDispatch.
  629. // Can we convert it to either one of these?
  630. // Try IDispatch first
  631. //
  632. VARIANT varDest;
  633. VariantInit(&varDest);
  634. HRESULT hr = VariantChangeType(&varDest, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)), 0, VT_DISPATCH);
  635. if (SUCCEEDED(hr)) {
  636. hr = _QueryInterface(V_DISPATCH(&varSrc));
  637. }
  638. if (FAILED(hr) && (hr == E_NOINTERFACE)) {
  639. // That failed ... so try IUnknown
  640. //
  641. VariantInit(&varDest);
  642. hr = VariantChangeType(&varDest, const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)), 0, VT_UNKNOWN);
  643. if (SUCCEEDED(hr)) {
  644. hr = _QueryInterface(V_UNKNOWN(&varSrc));
  645. }
  646. }
  647. VariantClear(&varDest);
  648. return hr;
  649. }
  650. };
  651. // Reverse comparison operators for _com_ptr_t
  652. //
  653. template<typename _InterfaceType> bool operator==(int null, _com_ptr_t<_InterfaceType>& p) throw(_com_error)
  654. {
  655. if (null != 0) {
  656. _com_issue_error(E_POINTER);
  657. }
  658. return p == NULL;
  659. }
  660. template<typename _Interface, typename _InterfacePtr> bool operator==(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  661. {
  662. return p == i;
  663. }
  664. template<typename _Interface> bool operator!=(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  665. {
  666. if (null != 0) {
  667. _com_issue_error(E_POINTER);
  668. }
  669. return p != NULL;
  670. }
  671. template<typename _Interface, typename _InterfacePtr> bool operator!=(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  672. {
  673. return p != i;
  674. }
  675. template<typename _Interface> bool operator<(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  676. {
  677. if (null != 0) {
  678. _com_issue_error(E_POINTER);
  679. }
  680. return p > NULL;
  681. }
  682. template<typename _Interface, typename _InterfacePtr> bool operator<(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  683. {
  684. return p > i;
  685. }
  686. template<typename _Interface> bool operator>(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  687. {
  688. if (null != 0) {
  689. _com_issue_error(E_POINTER);
  690. }
  691. return p < NULL;
  692. }
  693. template<typename _Interface, typename _InterfacePtr> bool operator>(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  694. {
  695. return p < i;
  696. }
  697. template<typename _Interface> bool operator<=(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  698. {
  699. if (null != 0) {
  700. _com_issue_error(E_POINTER);
  701. }
  702. return p >= NULL;
  703. }
  704. template<typename _Interface, typename _InterfacePtr> bool operator<=(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  705. {
  706. return p >= i;
  707. }
  708. template<typename _Interface> bool operator>=(int null, _com_ptr_t<_Interface>& p) throw(_com_error)
  709. {
  710. if (null != 0) {
  711. _com_issue_error(E_POINTER);
  712. }
  713. return p <= NULL;
  714. }
  715. template<typename _Interface, typename _InterfacePtr> bool operator>=(_Interface* i, _com_ptr_t<_InterfacePtr>& p) throw(_com_error)
  716. {
  717. return p <= i;
  718. }
  719. #if _MSC_VER >= 1200
  720. #pragma warning(pop)
  721. #endif
  722. #endif // _INC_COMIP