Leaked source code of windows server 2003
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.

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