ECUnknown.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #ifndef ECUNKNOWN_H
  18. #define ECUNKNOWN_H
  19. #include <kopano/zcdefs.h>
  20. #include <kopano/IECUnknown.h>
  21. #include <list>
  22. #include <mutex>
  23. #include <mapi.h>
  24. namespace KC {
  25. /**
  26. * Return interface pointer on a specific interface query.
  27. * @param[in] _guid The interface guid.
  28. * @param[in] _interface The class which implements the interface
  29. * @note guid variable must be named 'refiid', return variable must be named lppInterface.
  30. */
  31. #define REGISTER_INTERFACE(_guid, _interface) \
  32. do { \
  33. if (refiid == (_guid)) { \
  34. AddRef(); \
  35. *lppInterface = reinterpret_cast<void *>(_interface); \
  36. return hrSuccess; \
  37. } \
  38. } while (false)
  39. #define REGISTER_INTERFACE2(cls, interface) \
  40. do { \
  41. if (refiid == (IID_ ## cls)) { \
  42. AddRef(); \
  43. *lppInterface = static_cast<cls *>(interface); \
  44. return hrSuccess; \
  45. } \
  46. } while (false)
  47. #define REGISTER_INTERFACE3(guid, cls, interface) \
  48. do { \
  49. if (refiid == (IID_ ## guid)) { \
  50. AddRef(); \
  51. *lppInterface = static_cast<cls *>(interface); \
  52. return hrSuccess; \
  53. } \
  54. } while (false)
  55. /**
  56. * Return interface pointer on a specific interface query without incrementing the refcount.
  57. * @param[in] _guid The interface guid.
  58. * @param[in] _interface The class which implements the interface
  59. * @note guid variable must be named 'refiid', return variable must be named lppInterface.
  60. */
  61. #define REGISTER_INTERFACE_NOREF(_guid, _interface) \
  62. do { \
  63. if (refiid == (_guid)) { \
  64. AddRef(); \
  65. *lppInterface = reinterpret_cast<void *>(_interface); \
  66. return hrSuccess; \
  67. } \
  68. } while (false)
  69. class _kc_export ECUnknown : public IECUnknown {
  70. public:
  71. ECUnknown(const char *szClassName = NULL);
  72. virtual ~ECUnknown(void);
  73. virtual ULONG AddRef(void) _kc_override;
  74. virtual ULONG Release(void) _kc_override;
  75. virtual HRESULT QueryInterface(REFIID refiid, void **iface) _kc_override;
  76. virtual HRESULT AddChild(ECUnknown *lpChild);
  77. virtual HRESULT RemoveChild(ECUnknown *lpChild);
  78. class xUnknown _kc_final : public IUnknown {
  79. #include <kopano/xclsfrag/IUnknown.hpp>
  80. } m_xUnknown;
  81. // lpParent is public because it is always thread-safe and valid
  82. ECUnknown *lpParent = nullptr;
  83. virtual BOOL IsParentOf(const ECUnknown *lpObject);
  84. virtual BOOL IsChildOf(const ECUnknown *lpObject);
  85. protected:
  86. // Called by AddChild
  87. virtual HRESULT SetParent(ECUnknown *lpParent);
  88. // Kills itself when lstChildren.empty() AND m_cREF == 0
  89. virtual HRESULT Suicide();
  90. ULONG m_cRef = 0;
  91. const char *szClassName;
  92. std::list<ECUnknown *> lstChildren;
  93. std::mutex mutex;
  94. };
  95. } /* namespace */
  96. #endif // ECUNKNOWN_H