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.

199 lines
4.6 KiB

  1. #ifndef __SMART_COM_POINTER_H_
  2. #define __SMART_COM_POINTER_H_
  3. #include <comutil.h>
  4. ///////////////////////////////////////////////////////////////////////////////
  5. // ComPtr template class (smart pointer for a simple COM class which supports
  6. // no interfaces but IUnknown.
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #pragma warning(disable: 4290)
  9. // taken from _com_ptr_t definition in COMIP.h
  10. template<class CLS> class ComPtr
  11. {
  12. public:
  13. // Default constructor.
  14. ComPtr() throw()
  15. : m_pInterface(NULL) {}
  16. // This constructor is provided to allow NULL assignment. It will issue
  17. // an error if any value other than null is assigned to the object.
  18. ComPtr(int null) throw(_com_error)
  19. : m_pInterface(NULL)
  20. {
  21. if (null != 0) {
  22. _com_issue_error(E_POINTER);
  23. }
  24. }
  25. // Copy the pointer and AddRef().
  26. ComPtr(const ComPtr& cp) throw()
  27. : m_pInterface(cp.m_pInterface)
  28. { _AddRef(); }
  29. // Saves the interface.
  30. ComPtr(CLS* pInterface) throw()
  31. : m_pInterface(pInterface)
  32. { _AddRef(); }
  33. // Saves the interface.
  34. ComPtr& operator=(CLS* pInterface) throw()
  35. {
  36. if (m_pInterface != pInterface) {
  37. CLS* pOldInterface = m_pInterface;
  38. m_pInterface = pInterface;
  39. _AddRef();
  40. if (pOldInterface != NULL) {
  41. pOldInterface->Release();
  42. }
  43. }
  44. return *this;
  45. }
  46. // Copies and AddRef()'s the interface.
  47. ComPtr& operator=(const ComPtr& cp) throw()
  48. { return operator=(cp.m_pInterface); }
  49. // This operator is provided to permit the assignment of NULL to the class.
  50. // It will issue an error if any value other than NULL is assigned to it.
  51. ComPtr& operator=(int null) throw(_com_error)
  52. {
  53. if (null != 0) {
  54. _com_issue_error(E_POINTER);
  55. }
  56. return operator=(reinterpret_cast<CLS*>(NULL));
  57. }
  58. // If we still have an interface then Release() it. The interface
  59. // may be NULL if Detach() has previously been called, or if it was
  60. // never set.
  61. ~ComPtr() throw()
  62. { _Release(); }
  63. // Return the class ptr. This value may be NULL.
  64. operator CLS*() const throw()
  65. { return m_pInterface; }
  66. // Queries for the unknown and returns it
  67. // Provides minimal level error checking before use.
  68. operator CLS&() const throw(_com_error)
  69. {
  70. if (m_pInterface == NULL) {
  71. _com_issue_error(E_POINTER);
  72. }
  73. return *m_pInterface;
  74. }
  75. // Returns the address of the interface pointer contained in this
  76. // class. This is useful when using the COM/OLE interfaces to create
  77. // this interface.
  78. CLS** operator&() throw()
  79. {
  80. _Release();
  81. m_pInterface = NULL;
  82. return &m_pInterface;
  83. }
  84. // Allows this class to be used as the interface itself.
  85. // Also provides simple error checking.
  86. //
  87. CLS* operator->() const throw(_com_error)
  88. {
  89. if (m_pInterface == NULL) {
  90. _com_issue_error(E_POINTER);
  91. }
  92. return m_pInterface;
  93. }
  94. // This operator is provided so that simple boolean expressions will
  95. // work. For example: "if (p) ...".
  96. // Returns TRUE if the pointer is not NULL.
  97. operator bool() const throw()
  98. { return m_pInterface != NULL; }
  99. // Compare with other class ptr
  100. bool operator==(CLS* p) throw(_com_error)
  101. { return (m_pInterface == p); }
  102. // Compares 2 ComPtr's
  103. bool operator==(ComPtr& p) throw()
  104. { return operator==(p.m_pInterface); }
  105. // For comparison to NULL
  106. bool operator==(int null) throw(_com_error)
  107. {
  108. if (null != 0) {
  109. _com_issue_error(E_POINTER);
  110. }
  111. return m_pInterface == NULL;
  112. }
  113. // Compare with other interface
  114. bool operator!=(CLS* p) throw(_com_error)
  115. { return !(operator==(p)); }
  116. // Compares 2 ComPtr's
  117. bool operator!=(ComPtr& p) throw(_com_error)
  118. { return !(operator==(p)); }
  119. // For comparison to NULL
  120. bool operator!=(int null) throw(_com_error)
  121. { return !(operator==(null)); }
  122. // Provides error-checking Release()ing of this interface.
  123. void Release() throw(_com_error)
  124. {
  125. if (m_pInterface == NULL) {
  126. _com_issue_error(E_POINTER);
  127. }
  128. m_pInterface->Release();
  129. m_pInterface = NULL;
  130. }
  131. // Provides error-checking AddRef()ing of this interface.
  132. void AddRef() throw(_com_error)
  133. {
  134. if (m_pInterface == NULL) {
  135. _com_issue_error(E_POINTER);
  136. }
  137. m_pInterface->AddRef();
  138. }
  139. private:
  140. // The Interface.
  141. CLS* m_pInterface;
  142. // Releases only if the interface is not null.
  143. // The interface is not set to NULL.
  144. //
  145. void _Release() throw()
  146. {
  147. if (m_pInterface != NULL) {
  148. m_pInterface->Release();
  149. }
  150. }
  151. // AddRefs only if the interface is not NULL
  152. //
  153. void _AddRef() throw()
  154. {
  155. if (m_pInterface != NULL) {
  156. m_pInterface->AddRef();
  157. }
  158. }
  159. };
  160. #endif //__SMART_COM_POINTER_H_