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.

1293 lines
31 KiB

  1. #ifndef COMPTR_H
  2. #define COMPTR_H
  3. #if _MSC_VER >= 1100
  4. #pragma warning(disable:4800)
  5. #include <comdef.h>
  6. #define CIP_RETYPEDEF(I) typedef I##Ptr I##CIP;
  7. #define CIP_TYPEDEF(I) _COM_SMARTPTR_TYPEDEF(I, IID_##I); CIP_RETYPEDEF(I);
  8. #define DEFINE_CIP(x)\
  9. CIP_TYPEDEF(x)
  10. #define DECLARE_CIP(x) DEFINE_CIP(x) x##CIP
  11. CIP_RETYPEDEF(IUnknown);
  12. CIP_RETYPEDEF(IDataObject);
  13. CIP_RETYPEDEF(IStorage);
  14. CIP_RETYPEDEF(IStream);
  15. CIP_RETYPEDEF(IPersistStorage);
  16. CIP_RETYPEDEF(IPersistStream);
  17. CIP_RETYPEDEF(IPersistStreamInit);
  18. CIP_RETYPEDEF(IDispatch);
  19. #else // _MSC_VER < 1100
  20. #define USE_OLD_COMPILER (_MSC_VER<1100)
  21. #define USE_INTERMEDIATE_COMPILER (USE_OLD_COMPILER && (_MSC_VER>1020))
  22. // This avoids "warning C4290: C++ Exception Specification ignored"
  23. // JonN 12/16/96
  24. #pragma warning(4:4290)
  25. #ifndef BOOL_H
  26. #include <bool.h>
  27. #endif
  28. #ifndef __wtypes_h__
  29. #include <wtypes.h>
  30. #endif
  31. template<typename _Interface, const IID* _IID/*=&__uuidof(_Interface)*/>
  32. class CIID
  33. // Provide Interface to IID association
  34. {
  35. public: typedef _Interface Interface;
  36. public: static _Interface* GetInterfacePtr() throw()
  37. {
  38. return NULL;
  39. }
  40. public: static _Interface& GetInterface() throw()
  41. {
  42. return *GetInterfacePtr();
  43. }
  44. public: static const IID& GetIID() throw()
  45. {
  46. return *_IID;
  47. }
  48. }; // class CIID
  49. template<typename _CIID> class CIP
  50. {
  51. #if USE_OLD_COMPILER
  52. private: class _IUnknown: public IUnknown {};
  53. // Unique type used to provide for operations between different pointer
  54. // types.
  55. #endif // USE_OLD_COMPILER
  56. // Declare interface type so that the type may be available outside
  57. // the scope of this template.
  58. public: typedef _CIID ThisCIID;
  59. public: typedef _CIID::Interface Interface;
  60. public: static const IID& GetIID() throw()
  61. // When the compiler supports references in template params,
  62. // _CLSID will be changed to a reference. To avoid conversion
  63. // difficulties this function should be used to obtain the
  64. // CLSID.
  65. {
  66. return ThisCIID::GetIID();
  67. }
  68. //REVIEW: add support for assignment of nonpointer interfaces
  69. // i.e. IUnknown, instead of simple IUnknown*
  70. public: CIP() throw()
  71. // Construct empty in preperation for assignment.
  72. : _pInterface(NULL)
  73. {
  74. }
  75. public: CIP(int null) throw()
  76. // This constructor is provided to allow NULL assignment. It will assert
  77. // if any value other than null is assigned to the object.
  78. : _pInterface(NULL)
  79. {
  80. ASSERT(!null);
  81. }
  82. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  83. template<typename _InterfacePtr> CIP(_InterfacePtr p) throw()
  84. // Queries for this interface.
  85. #else
  86. public: CIP(_IUnknown& p) throw()
  87. : _pInterface(NULL)
  88. {
  89. if (&p)
  90. {
  91. const HRESULT hr = _QueryInterface(&p);
  92. ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
  93. }
  94. else _pInterface = NULL;
  95. }
  96. public: CIP(IUnknown* p) throw()
  97. #endif // !USE_OLD_COMPILER
  98. : _pInterface(NULL)
  99. {
  100. if (p)
  101. {
  102. const HRESULT hr = _QueryInterface(p);
  103. ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
  104. }
  105. else _pInterface = NULL;
  106. }
  107. public: CIP(const CIP& cp) throw()
  108. // Copy the pointer and AddRef().
  109. : _pInterface(cp._pInterface)
  110. {
  111. _AddRef();
  112. }
  113. public: CIP(Interface* pInterface) throw()
  114. // Saves the interface
  115. : _pInterface(pInterface)
  116. {
  117. _AddRef();
  118. }
  119. public: CIP(Interface* pInterface, bool bAddRef) throw()
  120. // Copies the pointer. If bAddRef is TRUE, the interface will
  121. // be AddRef()ed.
  122. : _pInterface(pInterface)
  123. {
  124. if (bAddRef)
  125. {
  126. ASSERT(!pInterface);
  127. if (pInterface)
  128. _AddRef();
  129. }
  130. }
  131. public: CIP(const CLSID& clsid, DWORD dwClsContext = CLSCTX_ALL) explicit throw()
  132. // Calls CoCreateClass with the provided CLSID.
  133. : _pInterface(NULL)
  134. {
  135. const HRESULT hr = CreateInstance(clsid, dwClsContext);
  136. ASSERT(SUCCEEDED(hr));
  137. }
  138. public: CIP(LPOLESTR str, DWORD dwClsContext = CLSCTX_ALL) explicit throw()
  139. // Calls CoCreateClass with the provided CLSID retrieved from
  140. // the string.
  141. : _pInterface(NULL)
  142. {
  143. const HRESULT hr = CreateInstance(str, dwClsContext);
  144. ASSERT(SUCCEEDED(hr));
  145. }
  146. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  147. public: template<typename _InterfacePtr> CIP& operator=(_InterfacePtr& p) throw()
  148. // Queries for interface.
  149. #else
  150. public: CIP& operator=(_IUnknown& p) throw()
  151. {
  152. return operator=(static_cast<IUnknown*>(&p));
  153. }
  154. public: CIP& operator=(IUnknown* p) throw()
  155. #endif // !USE_OLD_COMPILER
  156. {
  157. const HRESULT hr = _QueryInterface(p);
  158. ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
  159. return *this;
  160. }
  161. public: CIP& operator=(Interface* pInterface) throw()
  162. // Saves the interface.
  163. {
  164. if (_pInterface != pInterface)
  165. {
  166. Interface* pOldInterface = _pInterface;
  167. _pInterface = pInterface;
  168. _AddRef();
  169. if (pOldInterface)
  170. pOldInterface->Release();
  171. }
  172. return *this;
  173. }
  174. public: CIP& operator=(const CIP& cp) throw()
  175. // Copies and AddRef()'s the interface.
  176. {
  177. return operator=(cp._pInterface);
  178. }
  179. public: CIP& operator=(int null) throw()
  180. // This operator is provided to permit the assignment of NULL to the class.
  181. // It will assert if any value other than NULL is assigned to it.
  182. {
  183. ASSERT(!null);
  184. return operator=(reinterpret_cast<Interface*>(NULL));
  185. }
  186. public: ~CIP() throw()
  187. // If we still have an interface then Release() it. The interface
  188. // may be NULL if Detach() has previosly been called, or if it was
  189. // never set.
  190. {
  191. _Release();
  192. }
  193. public: void Attach(Interface* pInterface) throw()
  194. // Saves/sets the interface without AddRef()ing. This call
  195. // will release any previously aquired interface.
  196. {
  197. _Release();
  198. _pInterface = pInterface;
  199. }
  200. public: void Attach(Interface* pInterface, bool bAddRef) throw()
  201. // Saves/sets the interface only AddRef()ing if bAddRef is TRUE.
  202. // This call will release any previously aquired interface.
  203. {
  204. _Release();
  205. _pInterface = pInterface;
  206. if (bAddRef)
  207. {
  208. ASSERT(pInterface);
  209. if (pInterface)
  210. pInterface->AddRef();
  211. }
  212. }
  213. public: Interface* Detach() throw()
  214. // Simply NULL the interface pointer so that it isn't Released()'ed.
  215. {
  216. Interface* const old=_pInterface;
  217. _pInterface = NULL;
  218. return old;
  219. }
  220. public: operator Interface*() const throw()
  221. // Return the interface. This value may be NULL
  222. {
  223. return _pInterface;
  224. }
  225. public: Interface& operator*() const throw()
  226. // Allows an instance of this class to act as though it were the
  227. // actual interface. Also provides minimal assertion verification.
  228. {
  229. ASSERT(_pInterface);
  230. return *_pInterface;
  231. }
  232. public: Interface** operator&() throw()
  233. // Returns the address of the interface pointer contained in this
  234. // class. This is useful when using the COM/OLE interfaces to create
  235. // this interface.
  236. {
  237. _Release();
  238. _pInterface = NULL;
  239. return &_pInterface;
  240. }
  241. public: Interface* operator->() const throw()
  242. // Allows this class to be used as the interface itself.
  243. // Also provides simple assertion verification.
  244. {
  245. ASSERT(_pInterface);
  246. return _pInterface;
  247. }
  248. public: operator bool() const throw()
  249. // This operator is provided so that simple boolean expressions will
  250. // work. For example: "if (p) ...".
  251. // Returns TRUE if the pointer is not NULL.
  252. {
  253. return _pInterface;
  254. }
  255. public: bool operator!() throw()
  256. // Returns TRUE if the interface is NULL.
  257. // This operator will be removed when support for type bool
  258. // is added to the compiler.
  259. {
  260. return !_pInterface;
  261. }
  262. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  263. public: template<typename _InterfacePtr> bool operator==(_InterfacePtr p) throw()
  264. // Compare to pointers
  265. #else
  266. public: bool operator==(_IUnknown& p) throw()
  267. {
  268. return operator==(static_cast<IUnknown*>(&p));
  269. }
  270. public: bool operator==(IUnknown* p) throw()
  271. #endif // !USE_OLD_COMPILER
  272. {
  273. return !_CompareUnknown(p);
  274. }
  275. public: bool operator==(Interface* p) throw()
  276. // Compare with other interface
  277. {
  278. return (_pInterface == p) ? true : !_CompareUnknown(p);
  279. }
  280. public: bool operator==(CIP& p) throw()
  281. // Compares 2 CIPs
  282. {
  283. return operator==(p._pInterface);
  284. }
  285. public: bool operator==(int null) throw()
  286. // For comparison to NULL
  287. {
  288. ASSERT(!null);
  289. return !_pInterface;
  290. }
  291. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  292. public: template<typename _InterfacePtr> bool operator!=(_InterfacePtr p) throw()
  293. // Compare to pointers
  294. #else
  295. public: bool operator!=(_IUnknown& p) throw()
  296. {
  297. return operator!=(static_cast<IUnknown*>(&p));
  298. }
  299. public: bool operator!=(IUnknown* p) throw()
  300. #endif // !USE_OLD_COMPILER
  301. {
  302. return _CompareUnknown(p);
  303. }
  304. public: bool operator!=(Interface* p) throw()
  305. // Compare with other interface
  306. {
  307. return (_pInterface!=p)?true:_CompareUnknown(p);
  308. }
  309. public: bool operator!=(CIP& p) throw()
  310. // Compares 2 CIPs
  311. {
  312. return operator!=(p._pInterface);
  313. }
  314. public: bool operator!=(int null) throw()
  315. // For comparison to NULL
  316. {
  317. ASSERT(!null);
  318. return _pInterface;
  319. }
  320. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  321. public: template<typename _InterfacePtr> bool operator<(_InterfacePtr p) throw()
  322. // Compare to pointers
  323. #else
  324. public: bool operator<(_IUnknown& p) throw()
  325. {
  326. return operator<(static_cast<IUnknown*>(&p));
  327. }
  328. public: bool operator<(IUnknown* p) throw()
  329. #endif // !USE_OLD_COMPILER
  330. {
  331. return _CompareUnknown(p)<0;
  332. }
  333. public: bool operator<(Interface* p) throw()
  334. // Compare with other interface
  335. {
  336. return (_pInterface<p) ? true : _CompareUnknown(p) < 0;
  337. }
  338. public: bool operator<(CIP& p) throw()
  339. // Compares 2 CIPs
  340. {
  341. return operator<(p._pInterface);
  342. }
  343. public: bool operator<(int null) throw()
  344. // For comparison with NULL
  345. {
  346. ASSERT(!null);
  347. return _pInterface<NULL;
  348. }
  349. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  350. public: template<typename _InterfacePtr> bool operator>(_InterfacePtr p) throw()
  351. // Compare to pointers
  352. #else
  353. public: bool operator>(_IUnknown& p) throw()
  354. {
  355. return operator>(static_cast<IUnknown*>(&p));
  356. }
  357. public: bool operator>(IUnknown* p) throw()
  358. #endif // !USE_OLD_COMPILER
  359. {
  360. return _CompareUnknown(p) > 0;
  361. }
  362. public: bool operator>(Interface* p) throw()
  363. // Compare with other interface
  364. {
  365. return (_pInterface>p) ? true : _CompareUnknown(p) > 0;
  366. }
  367. public: bool operator>(CIP& p) throw()
  368. // Compares 2 CIPs
  369. {
  370. return operator>(p._pInterface);
  371. }
  372. public: bool operator>(int null) throw()
  373. // For comparison with NULL
  374. {
  375. ASSERT(!null);
  376. return _pInterface > NULL;
  377. }
  378. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  379. public: template<typename _InterfacePtr> bool operator<=(_InterfacePtr p) throw()
  380. // Compare to pointers
  381. #else
  382. public: bool operator<=(_IUnknown& p) throw()
  383. {
  384. return operator<=(static_cast<IUnknown*>(&p));
  385. }
  386. public: bool operator<=(IUnknown* p) throw()
  387. #endif // !USE_OLD_COMPILER
  388. {
  389. return _CompareUnknown(p)<=0;
  390. }
  391. public: bool operator<=(Interface* p) throw()
  392. // Compare with other interface
  393. {
  394. return (_pInterface<=p) ? true : _CompareUnknown(p) <= 0;
  395. }
  396. public: bool operator<=(CIP& p) throw()
  397. // Compares 2 CIPs
  398. {
  399. return operator<=(p._pInterface);
  400. }
  401. public: bool operator<=(int null) throw()
  402. // For comparison with NULL
  403. {
  404. ASSERT(!null);
  405. return _pInterface <= NULL;
  406. }
  407. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  408. public: template<typename _InterfacePtr> bool operator>=(_InterfacePtr p) throw()
  409. // Compare to pointers
  410. #else
  411. public: bool operator>=(_IUnknown& p) throw()
  412. {
  413. return operator>=(static_cast<IUnknown*>(&p));
  414. }
  415. public: bool operator>=(IUnknown* p) throw()
  416. #endif // !USE_OLD_COMPILER
  417. {
  418. return _CompareUnknown(p) >= 0;
  419. }
  420. public: bool operator>=(Interface* p) throw()
  421. // Compare with other interface
  422. {
  423. return (_pInterface>=p) ? true : _CompareUnknown(p) >= 0;
  424. }
  425. public: bool operator>=(CIP& p) throw()
  426. // Compares 2 CIPs
  427. {
  428. return operator>=(p._pInterface);
  429. }
  430. public: bool operator>=(int null) throw()
  431. // For comparison with NULL
  432. {
  433. ASSERT(!null);
  434. return _pInterface >= NULL;
  435. }
  436. #if USE_OLD_COMPILER
  437. public: operator _IUnknown&() const throw()
  438. // Provided for casts between different pointer types.
  439. {
  440. return *reinterpret_cast<_IUnknown*>(static_cast<IUnknown*>(_pInterface));
  441. }
  442. #endif // USE_OLD_COMPILER
  443. public: void Release() throw()
  444. // Provides assertion verified, Release()ing of this interface.
  445. {
  446. ASSERT(_pInterface);
  447. if (_pInterface)
  448. {
  449. _pInterface->Release();
  450. _pInterface = NULL;
  451. }
  452. }
  453. public: void AddRef() throw()
  454. // Provides assertion verified AddRef()ing of this interface.
  455. {
  456. ASSERT(_pInterface);
  457. if (_pInterface)
  458. _pInterface->AddRef();
  459. }
  460. public: Interface* GetInterfacePtr() const throw()
  461. // Another way to get the interface pointer without casting.
  462. {
  463. return _pInterface;
  464. }
  465. public: HRESULT CreateInstance(
  466. const CLSID& clsid, DWORD dwClsContext=CLSCTX_ALL) throw()
  467. // Loads an interface for the provided CLSID.
  468. // Returns an HRESULT. Any previous interface is released.
  469. {
  470. _Release();
  471. const HRESULT hr = CoCreateInstance(clsid, NULL, dwClsContext,
  472. GetIID(), reinterpret_cast<void**>(&_pInterface));
  473. ASSERT(SUCCEEDED(hr));
  474. return hr;
  475. }
  476. public: HRESULT CreateInstance(
  477. LPOLESTR clsidString, DWORD dwClsContext=CLSCTX_ALL) throw()
  478. // Creates the class specified by clsidString. clsidString may
  479. // contain a class id, or a prog id string.
  480. {
  481. // ISSUE-2002/03/29-JonN Should handle NULL case
  482. ASSERT(clsidString);
  483. CLSID clsid;
  484. HRESULT hr;
  485. if (clsidString[0] == '{')
  486. hr = CLSIDFromString(clsidString, &clsid);
  487. else
  488. hr = CLSIDFromProgID(clsidString, &clsid);
  489. ASSERT(SUCCEEDED(hr));
  490. if (FAILED(hr))
  491. return hr;
  492. return CreateInstance(clsid, dwClsContext);
  493. }
  494. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  495. public: template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType*& p) throw()
  496. // Perfoms the QI for the specified IID and returns it in p.
  497. // As with all QIs, the interface will be AddRef'd.
  498. #else
  499. public: HRESULT QueryInterface(const IID& iid, IUnknown*& p) throw()
  500. #endif // !USE_OLD_COMPILER
  501. {
  502. return _pInterface ?
  503. _pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p)) :
  504. E_NOINTERFACE;
  505. }
  506. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  507. public: template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid, _InterfaceType** p) throw()
  508. // Perfoms the QI for the specified IID and returns it in p.
  509. // As with all QIs, the interface will be AddRef'd.
  510. #else
  511. public: HRESULT QueryInterface(const IID& iid, IUnknown** p) throw()
  512. #endif // !USE_OLD_COMPILER
  513. {
  514. return QueryInterface(iid, *p);
  515. }
  516. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  517. public: template<typename _InterfaceType> _InterfaceType* QueryInterface(const IID& iid) throw()
  518. // Perfoms the QI for the specified IID and returns it.
  519. // As with all QIs, the interface will be AddRef'd.
  520. #else
  521. public: IUnknown* QueryInterface(const IID& iid) throw()
  522. #endif // !USE_OLD_COMPILER
  523. {
  524. #if USE_OLD_COMPILER
  525. typedef IUnknown _InterfaceType;
  526. #endif // USE_OLD_COMPILER
  527. _InterfaceType* pInterface;
  528. QueryInterface(iid, pInterface);
  529. return pInterface;
  530. }
  531. private: Interface* _pInterface;
  532. // The Interface.
  533. private: void _Release() throw()
  534. // Releases only if the interface is not null.
  535. // The interface is not set to NULL.
  536. {
  537. if (_pInterface)
  538. _pInterface->Release();
  539. }
  540. private: void _AddRef() throw()
  541. // AddRefs only if the interface is not NULL
  542. {
  543. if (_pInterface)
  544. _pInterface->AddRef();
  545. }
  546. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  547. private: template<typename _InterfacePtr> HRESULT _QueryInterface(_InterfacePtr p) throw()
  548. // Performs a QI on pUnknown for the interface type returned
  549. // for this class. The interface is stored. If pUnknown is
  550. // NULL, or the QI fails, E_NOINTERFACE is returned and
  551. // _pInterface is set to NULL.
  552. #else
  553. private: HRESULT _QueryInterface(IUnknown* p) throw()
  554. #endif // !USE_OLD_COMPILER
  555. {
  556. if (!p) // Can't QI NULL
  557. {
  558. operator=(static_cast<Interface*>(NULL));
  559. return E_NOINTERFACE;
  560. }
  561. // Query for this interface
  562. Interface* pInterface;
  563. const HRESULT hr = p->QueryInterface(GetIID(),
  564. reinterpret_cast<void**>(&pInterface));
  565. if (FAILED(hr))
  566. {
  567. // If failed intialize interface to NULL and return HRESULT.
  568. Attach(NULL);
  569. return hr;
  570. }
  571. // Save the interface without AddRef()ing.
  572. Attach(pInterface);
  573. return hr;
  574. }
  575. #if !USE_OLD_COMPILER //REVIEW: remove after v5
  576. private: template<typename _InterfacePtr> int _CompareUnknown(_InterfacePtr& p) throw()
  577. // Compares the provided pointer with this by obtaining IUnknown interfaces
  578. // for each pointer and then returning the difference.
  579. #else
  580. private: int _CompareUnknown(IUnknown* p) throw()
  581. #endif // !USE_OLD_COMPILER
  582. {
  583. IUnknown* pu1;
  584. if (_pInterface)
  585. {
  586. const HRESULT hr = QueryInterface(IID_IUnknown, pu1);
  587. ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
  588. if (pu1)
  589. pu1->Release();
  590. }
  591. else pu1=NULL;
  592. IUnknown* pu2;
  593. if (p)
  594. {
  595. const HRESULT hr = p->QueryInterface(IID_IUnknown, reinterpret_cast<void**>(&pu2));
  596. ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
  597. if (pu2)
  598. pu2->Release();
  599. }
  600. else pu2 = NULL;
  601. return pu1 - pu2;
  602. }
  603. }; // class CIP
  604. // Reverse comparison operators for CIP
  605. template<typename _Interface> bool operator==(int null, CIP<_Interface>& p)
  606. {
  607. ASSERT(!null);
  608. return p == NULL;
  609. }
  610. template<typename _Interface, typename _InterfacePtr> bool operator==(_Interface* i, CIP<_InterfacePtr>& p)
  611. {
  612. return p == i;
  613. }
  614. template<typename _Interface> bool operator!=(int null, CIP<_Interface>& p)
  615. {
  616. ASSERT(!null);
  617. return p != NULL;
  618. }
  619. template<typename _Interface, typename _InterfacePtr> bool operator!=(_Interface* i, CIP<_InterfacePtr>& p)
  620. {
  621. return p != i;
  622. }
  623. template<typename _Interface> bool operator<(int null, CIP<_Interface>& p)
  624. {
  625. ASSERT(!null);
  626. return p < NULL;
  627. }
  628. template<typename _Interface, typename _InterfacePtr> bool operator<(_Interface* i, CIP<_InterfacePtr>& p)
  629. {
  630. return p < i;
  631. }
  632. template<typename _Interface> bool operator>(int null, CIP<_Interface>& p)
  633. {
  634. ASSERT(!null);
  635. return p > NULL;
  636. }
  637. template<typename _Interface, typename _InterfacePtr> bool operator>(_Interface* i, CIP<_InterfacePtr>& p)
  638. {
  639. return p > i;
  640. }
  641. template<typename _Interface> bool operator<=(int null, CIP<_Interface>& p)
  642. {
  643. ASSERT(!null);
  644. return p <= NULL;
  645. }
  646. template<typename _Interface, typename _InterfacePtr> bool operator<=(_Interface* i, CIP<_InterfacePtr>& p)
  647. {
  648. return p <= i;
  649. }
  650. template<typename _Interface> bool operator>=(int null, CIP<_Interface>& p)
  651. {
  652. ASSERT(!null);
  653. return p >= NULL;
  654. }
  655. template<typename _Interface, typename _InterfacePtr> bool operator>=(_Interface* i, CIP<_InterfacePtr>& p)
  656. {
  657. return p >= i;
  658. }
  659. #define DEFINE_CIP(x)\
  660. typedef CIID<x, &IID_##x> x##IID;\
  661. typedef CIP<x##IID> x##CIP;
  662. #define DECLARE_CIP(x) DEFINE_CIP(x) x##CIP
  663. DEFINE_CIP(IUnknown);
  664. #if USE_OLD_COMPILER
  665. #if USE_INTERMEDIATE_COMPILER
  666. template<>
  667. #endif
  668. class CIP<IUnknownIID>
  669. {
  670. private:
  671. #if USE_OLD_COMPILER
  672. // Unique type used to provide for operations between different pointer
  673. // types.
  674. class _IUnknown: public IUnknown {};
  675. #endif // USE_OLD_COMPILER
  676. public:
  677. // Declare interface type so that the type may be available outside
  678. // the scope of this template.
  679. typedef IUnknownIID ThisCIID;
  680. typedef IUnknown Interface;
  681. // When the compiler supports references in template params,
  682. // _CLSID will be changed to a reference. To avoid conversion
  683. // difficulties this function should be used to obtain the
  684. // CLSID.
  685. static const IID& GetIID() throw()
  686. {
  687. return ThisCIID::GetIID();
  688. }
  689. // Construct empty in preperation for assignment.
  690. CIP() throw()
  691. : _pInterface(NULL)
  692. {
  693. }
  694. // This constructor is provided to allow NULL assignment. It will assert
  695. // if any value other than null is assigned to the object.
  696. CIP(int null) throw()
  697. : _pInterface(NULL)
  698. {
  699. ASSERT(!null);
  700. }
  701. CIP(_IUnknown& p) throw()
  702. : _pInterface(NULL)
  703. {
  704. if (&p)
  705. {
  706. const HRESULT hr=_QueryInterface(&p);
  707. ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
  708. }
  709. else _pInterface=NULL;
  710. }
  711. // Copy the pointer and AddRef().
  712. CIP(const CIP& cp) throw()
  713. : _pInterface(cp._pInterface)
  714. {
  715. _AddRef();
  716. }
  717. // Saves the interface
  718. CIP(Interface* pInterface) throw()
  719. : _pInterface(pInterface)
  720. {
  721. _AddRef();
  722. }
  723. // Copies the pointer. If bAddRef is TRUE, the interface will
  724. // be AddRef()ed.
  725. CIP(Interface* pInterface, bool bAddRef) throw()
  726. : _pInterface(pInterface)
  727. {
  728. if (bAddRef)
  729. {
  730. ASSERT(!pInterface);
  731. _AddRef();
  732. }
  733. }
  734. // Calls CoCreateClass with the provided CLSID.
  735. CIP(const CLSID& clsid, DWORD dwClsContext = CLSCTX_ALL) explicit throw()
  736. : _pInterface(NULL)
  737. {
  738. const HRESULT hr = CreateInstance(clsid, dwClsContext);
  739. ASSERT(SUCCEEDED(hr));
  740. }
  741. // Calls CoCreateClass with the provided CLSID retrieved from
  742. // the string.
  743. CIP(LPOLESTR str, DWORD dwClsContext = CLSCTX_ALL) explicit throw()
  744. : _pInterface(NULL)
  745. {
  746. const HRESULT hr = CreateInstance(str, dwClsContext);
  747. ASSERT(SUCCEEDED(hr));
  748. }
  749. CIP& operator=(_IUnknown& p) throw()
  750. {
  751. return operator=(static_cast<IUnknown*>(&p));
  752. }
  753. // Saves the interface.
  754. CIP& operator=(Interface* pInterface) throw()
  755. {
  756. if (_pInterface != pInterface)
  757. {
  758. Interface* pOldInterface = _pInterface;
  759. _pInterface = pInterface;
  760. _AddRef();
  761. if (pOldInterface)
  762. pOldInterface->Release();
  763. }
  764. return *this;
  765. }
  766. // Copies and AddRef()'s the interface.
  767. CIP& operator=(const CIP& cp) throw()
  768. {
  769. return operator=(cp._pInterface);
  770. }
  771. // This operator is provided to permit the assignment of NULL to the class.
  772. // It will assert if any value other than NULL is assigned to it.
  773. CIP& operator=(int null) throw()
  774. {
  775. ASSERT(!null);
  776. return operator=(reinterpret_cast<Interface*>(NULL));
  777. }
  778. // If we still have an interface then Release() it. The interface
  779. // may be NULL if Detach() has previosly been called, or if it was
  780. // never set.
  781. ~CIP() throw()
  782. {
  783. _Release();
  784. }
  785. // Saves/sets the interface without AddRef()ing. This call
  786. // will release any previously aquired interface.
  787. void Attach(Interface* pInterface) throw()
  788. {
  789. _Release();
  790. _pInterface = pInterface;
  791. }
  792. // Saves/sets the interface only AddRef()ing if bAddRef is TRUE.
  793. // This call will release any previously aquired interface.
  794. void Attach(Interface* pInterface, bool bAddRef) throw()
  795. {
  796. _Release();
  797. _pInterface = pInterface;
  798. if (bAddRef)
  799. {
  800. ASSERT(pInterface);
  801. if (pInterface)
  802. pInterface->AddRef();
  803. }
  804. }
  805. // Simply NULL the interface pointer so that it isn't Released()'ed.
  806. IUnknown* Detach() throw()
  807. {
  808. ASSERT(_pInterface);
  809. IUnknown* const old = _pInterface;
  810. _pInterface = NULL;
  811. return old;
  812. }
  813. // Return the interface. This value may be NULL
  814. operator Interface*() const throw()
  815. {
  816. return _pInterface;
  817. }
  818. // Queries for the unknown and return it
  819. // Provides minimal level assertion before use.
  820. operator Interface&() const throw()
  821. {
  822. ASSERT(_pInterface);
  823. return *_pInterface;
  824. }
  825. // Allows an instance of this class to act as though it were the
  826. // actual interface. Also provides minimal assertion verification.
  827. Interface& operator*() const throw()
  828. {
  829. ASSERT(_pInterface);
  830. return *_pInterface;
  831. }
  832. // Returns the address of the interface pointer contained in this
  833. // class. This is useful when using the COM/OLE interfaces to create
  834. // this interface.
  835. Interface** operator&() throw()
  836. {
  837. _Release();
  838. _pInterface = NULL;
  839. return &_pInterface;
  840. }
  841. // Allows this class to be used as the interface itself.
  842. // Also provides simple assertion verification.
  843. Interface* operator->() const throw()
  844. {
  845. ASSERT(_pInterface);
  846. return _pInterface;
  847. }
  848. // This operator is provided so that simple boolean expressions will
  849. // work. For example: "if (p) ...".
  850. // Returns TRUE if the pointer is not NULL.
  851. operator bool() const throw()
  852. {
  853. return _pInterface;
  854. }
  855. // Returns TRUE if the interface is NULL.
  856. // This operator will be removed when support for type bool
  857. // is added to the compiler.
  858. bool operator!() throw()
  859. {
  860. return !_pInterface;
  861. }
  862. bool operator==(_IUnknown& p) throw()
  863. {
  864. return operator==(static_cast<IUnknown*>(&p));
  865. }
  866. // Compare with other interface
  867. bool operator==(Interface* p) throw()
  868. {
  869. return (_pInterface==p)?true:!_CompareUnknown(p);
  870. }
  871. // Compares 2 CIPs
  872. bool operator==(CIP& p) throw()
  873. {
  874. return operator==(p._pInterface);
  875. }
  876. // For comparison to NULL
  877. bool operator==(int null) throw()
  878. {
  879. ASSERT(!null);
  880. return !_pInterface;
  881. }
  882. bool operator!=(_IUnknown& p) throw()
  883. {
  884. return operator!=(static_cast<IUnknown*>(&p));
  885. }
  886. // Compare with other interface
  887. bool operator!=(Interface* p) throw()
  888. {
  889. return (_pInterface!=p)?true:_CompareUnknown(p);
  890. }
  891. // Compares 2 CIPs
  892. bool operator!=(CIP& p) throw()
  893. {
  894. return operator!=(p._pInterface);
  895. }
  896. // For comparison to NULL
  897. bool operator!=(int null) throw()
  898. {
  899. ASSERT(!null);
  900. return _pInterface;
  901. }
  902. bool operator<(_IUnknown& p) throw()
  903. {
  904. return operator<(static_cast<IUnknown*>(&p));
  905. }
  906. // Compare with other interface
  907. bool operator<(Interface* p) throw()
  908. {
  909. return (_pInterface<p)?true:_CompareUnknown(p)<0;
  910. }
  911. // Compares 2 CIPs
  912. bool operator<(CIP& p) throw()
  913. {
  914. return operator<(p._pInterface);
  915. }
  916. // For comparison with NULL
  917. bool operator<(int null) throw()
  918. {
  919. ASSERT(!null);
  920. return _pInterface<NULL;
  921. }
  922. bool operator>(_IUnknown& p) throw()
  923. {
  924. return operator>(static_cast<IUnknown*>(&p));
  925. }
  926. // Compare with other interface
  927. bool operator>(Interface* p) throw()
  928. {
  929. return (_pInterface>p)?true:_CompareUnknown(p)>0;
  930. }
  931. // Compares 2 CIPs
  932. bool operator>(CIP& p) throw()
  933. {
  934. return operator>(p._pInterface);
  935. }
  936. // For comparison with NULL
  937. bool operator>(int null) throw()
  938. {
  939. ASSERT(!null);
  940. return _pInterface>NULL;
  941. }
  942. bool operator<=(_IUnknown& p) throw()
  943. {
  944. return operator<=(static_cast<IUnknown*>(&p));
  945. }
  946. // Compare with other interface
  947. bool operator<=(Interface* p) throw()
  948. {
  949. return (_pInterface<=p)?true:_CompareUnknown(p)<=0;
  950. }
  951. // Compares 2 CIPs
  952. bool operator<=(CIP& p) throw()
  953. {
  954. return operator<=(p._pInterface);
  955. }
  956. // For comparison with NULL
  957. bool operator<=(int null) throw()
  958. {
  959. ASSERT(!null);
  960. return _pInterface<=NULL;
  961. }
  962. bool operator>=(_IUnknown& p) throw()
  963. {
  964. return operator>=(static_cast<IUnknown*>(&p));
  965. }
  966. // Compare with other interface
  967. bool operator>=(Interface* p) throw()
  968. {
  969. return (_pInterface>=p)?true:_CompareUnknown(p)>=0;
  970. }
  971. // Compares 2 CIPs
  972. bool operator>=(CIP& p) throw()
  973. {
  974. return operator>=(p._pInterface);
  975. }
  976. // For comparison with NULL
  977. bool operator>=(int null) throw()
  978. {
  979. ASSERT(!null);
  980. return _pInterface>=NULL;
  981. }
  982. // Provided for casts between different pointer types.
  983. operator _IUnknown&() const throw()
  984. {
  985. return *reinterpret_cast<_IUnknown*>(static_cast<IUnknown*>(_pInterface));
  986. }
  987. // Provides assertion verified, Release()ing of this interface.
  988. void Release() throw()
  989. {
  990. ASSERT(_pInterface);
  991. if (_pInterface)
  992. {
  993. _pInterface->Release();
  994. _pInterface = NULL;
  995. }
  996. }
  997. // Provides assertion verified AddRef()ing of this interface.
  998. void AddRef() throw()
  999. {
  1000. ASSERT(_pInterface);
  1001. if (_pInterface)
  1002. _pInterface->AddRef();
  1003. }
  1004. // Another way to get the interface pointer without casting.
  1005. Interface* GetInterfacePtr() const throw()
  1006. {
  1007. return _pInterface;
  1008. }
  1009. // Loads an interface for the provided CLSID.
  1010. // Returns an HRESULT. Any previous interface is released.
  1011. HRESULT CreateInstance(
  1012. const CLSID& clsid, DWORD dwClsContext=CLSCTX_ALL) throw()
  1013. {
  1014. _Release();
  1015. const HRESULT hr = CoCreateInstance(clsid, NULL, dwClsContext,
  1016. GetIID(), reinterpret_cast<void**>(&_pInterface));
  1017. ASSERT(SUCCEEDED(hr));
  1018. return hr;
  1019. }
  1020. // Creates the class specified by clsidString. clsidString may
  1021. // contain a class id, or a prog id string.
  1022. HRESULT CreateInstance(
  1023. LPOLESTR clsidString, DWORD dwClsContext=CLSCTX_ALL) throw()
  1024. {
  1025. // ISSUE-2002/03/29-JonN Should handle NULL case
  1026. ASSERT(clsidString);
  1027. CLSID clsid;
  1028. HRESULT hr;
  1029. if (clsidString[0] == '{')
  1030. hr = CLSIDFromString(clsidString, &clsid);
  1031. else
  1032. hr = CLSIDFromProgID(clsidString, &clsid);
  1033. ASSERT(SUCCEEDED(hr));
  1034. if (FAILED(hr))
  1035. return hr;
  1036. return CreateInstance(clsid, dwClsContext);
  1037. }
  1038. HRESULT QueryInterface(const IID& iid, IUnknown*& p) throw()
  1039. {
  1040. return _pInterface ?
  1041. _pInterface->QueryInterface(iid, reinterpret_cast<void**>(&p)) :
  1042. E_NOINTERFACE;
  1043. }
  1044. HRESULT QueryInterface(const IID& iid, IUnknown** p) throw()
  1045. {
  1046. return QueryInterface(iid, *p);
  1047. }
  1048. // Perfoms the QI for the specified IID and returns it.
  1049. // As with all QIs, the interface will be AddRef'd.
  1050. IUnknown* QueryInterface(const IID& iid) throw()
  1051. {
  1052. typedef IUnknown _InterfaceType;
  1053. _InterfaceType* pInterface;
  1054. QueryInterface(iid, pInterface);
  1055. return pInterface;
  1056. }
  1057. private:
  1058. // The Interface.
  1059. Interface* _pInterface;
  1060. // Releases only if the interface is not null.
  1061. // The interface is not set to NULL.
  1062. void _Release() throw()
  1063. {
  1064. if (_pInterface)
  1065. _pInterface->Release();
  1066. }
  1067. // AddRefs only if the interface is not NULL
  1068. void _AddRef() throw()
  1069. {
  1070. if (_pInterface)
  1071. _pInterface->AddRef();
  1072. }
  1073. // Performs a QI on pUnknown for the interface type returned
  1074. // for this class. The interface is stored. If pUnknown is
  1075. // NULL, or the QI fails, E_NOINTERFACE is returned and
  1076. // _pInterface is set to NULL.
  1077. HRESULT _QueryInterface(IUnknown* p) throw()
  1078. {
  1079. if (!p) // Can't QI NULL
  1080. {
  1081. operator=(static_cast<Interface*>(NULL));
  1082. return E_NOINTERFACE;
  1083. }
  1084. // Query for this interface
  1085. Interface* pInterface;
  1086. const HRESULT hr = p->QueryInterface(GetIID(),
  1087. reinterpret_cast<void**>(&pInterface));
  1088. if (FAILED(hr))
  1089. {
  1090. // If failed intialize interface to NULL and return HRESULT.
  1091. Attach(NULL);
  1092. return hr;
  1093. }
  1094. // Save the interface without AddRef()ing.
  1095. Attach(pInterface);
  1096. return hr;
  1097. }
  1098. // Compares the provided pointer with this by obtaining IUnknown interfaces
  1099. // for each pointer and then returning the difference.
  1100. int _CompareUnknown(IUnknown* p) throw()
  1101. {
  1102. IUnknown* pu1;
  1103. if (_pInterface)
  1104. {
  1105. const HRESULT hr=QueryInterface(IID_IUnknown, pu1);
  1106. ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
  1107. if (pu1)
  1108. pu1->Release();
  1109. }
  1110. else pu1=NULL;
  1111. IUnknown* pu2;
  1112. if (p)
  1113. {
  1114. const HRESULT hr=p->QueryInterface(IID_IUnknown, reinterpret_cast<void**>(&pu2));
  1115. ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE);
  1116. if (pu2)
  1117. pu2->Release();
  1118. }
  1119. else pu2=NULL;
  1120. return pu1-pu2;
  1121. }
  1122. }; // class CIP
  1123. #endif // USE_OLD_COMPILER
  1124. #endif // _MSC_VER < 1100
  1125. #endif // COMPTR_H