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.

140 lines
4.3 KiB

  1. // Copyright 1995-1997 Microsoft Corporation. All Rights Reserved.
  2. #if _MSC_VER > 1000
  3. #pragma once
  4. #endif
  5. #ifndef _UNKNOWN_H_
  6. #define _UNKNOWN_H_
  7. //=--------------------------------------------------------------------------=
  8. // UNKNOWNOBJECTINFO
  9. //
  10. // if you want a simple co-creatable object, with no other guarantees about
  11. // it, then you need to put the following entry in the global table of objects.
  12. // other object types that are more complex, such as automation objects, and
  13. // controls, will also use this information...
  14. typedef struct {
  15. const CLSID *rclsid; // CLSID of your object. ONLY USE IF YOU'RE CoCreatable!
  16. LPCSTR pszObjectName; // Name of your object. ONLY USE IF YOU'RE CoCreatable!
  17. IUnknown *(*pfnCreate)(IUnknown *); // pointer to creation fn. ONLY USE IF YOU'RE CoCreatable!
  18. } UNKNOWNOBJECTINFO;
  19. #define NAMEOFOBJECT(index) (((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pszObjectName)
  20. #define CLSIDOFOBJECT(index) (*(((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->rclsid))
  21. #define CREATEFNOFOBJECT(index) (((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pfnCreate)
  22. #ifndef INITOBJECTS
  23. #define DEFINE_UNKNOWNOBJECT(name, clsid, objname, fn) \
  24. extern UNKNOWNOBJECTINFO name##Object \
  25. #else
  26. #define DEFINE_UNKNOWNOBJECT(name, clsid, objname, fn) \
  27. UNKNOWNOBJECTINFO name##Object = { clsid, objname, fn } \
  28. #endif // INITOBJECTS
  29. //=--------------------------------------------------------------------------=
  30. // DECLARE_STANDARD_UNKNOWN
  31. //
  32. // All objects that are going to inherit from CUnknown for their IUnknown
  33. // implementation should put this in their class declaration instead of the
  34. // three IUnknown methods.
  35. //
  36. #define DECLARE_STANDARD_UNKNOWN() \
  37. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut) { \
  38. return ExternalQueryInterface(riid, ppvObjOut); \
  39. } \
  40. STDMETHOD_(ULONG, AddRef)(void) { \
  41. return ExternalAddRef(); \
  42. } \
  43. STDMETHOD_(ULONG, Release)(void) { \
  44. return ExternalRelease(); \
  45. } \
  46. // global variable where we store the current lock count on our DLL. This resides
  47. // in InProcServer.Cpp
  48. extern LONG g_cLocks;
  49. //=--------------------------------------------------------------------------=
  50. // this class doesn't inherit from IUnknown since people inheriting from it
  51. // are going to do so, and just delegate their IUnknown calls to the External*
  52. // member functions on this object. the internal private unknown object does
  53. // need to inherit from IUnknown, since it will be used directly as an IUnknown
  54. // object.
  55. class CUnknownObject
  56. {
  57. public:
  58. CUnknownObject(IUnknown *pUnkOuter, void *pvInterface)
  59. : m_pvInterface(pvInterface),
  60. m_pUnkOuter((pUnkOuter) ? pUnkOuter : &m_UnkPrivate)
  61. { InterlockedIncrement(&g_cLocks); }
  62. CUnknownObject(IUnknown *pUnkOuter) {
  63. m_pUnkOuter = pUnkOuter ? pUnkOuter : &m_UnkPrivate;
  64. InterlockedIncrement(&g_cLocks);
  65. }
  66. virtual ~CUnknownObject() { InterlockedDecrement(&g_cLocks); }
  67. // these are all protected so that classes that inherit from this can
  68. // at get at them.
  69. protected:
  70. // IUnknown methods. these just delegate to the controlling
  71. // unknown.
  72. HRESULT ExternalQueryInterface(REFIID riid, void **ppvObjOut) {
  73. return m_pUnkOuter->QueryInterface(riid, ppvObjOut);
  74. }
  75. ULONG ExternalAddRef(void) {
  76. return m_pUnkOuter->AddRef();
  77. }
  78. ULONG ExternalRelease(void) {
  79. return m_pUnkOuter->Release();
  80. }
  81. // people should use this during creation to return their private
  82. // unknown
  83. //
  84. inline IUnknown *PrivateUnknown (void) {
  85. return &m_UnkPrivate;
  86. }
  87. virtual HRESULT InternalQueryInterface(REFIID riid, void **ppvObjOut);
  88. IUnknown *m_pUnkOuter; // outer controlling Unknown
  89. void *m_pvInterface; // the real interface we're working with.
  90. private:
  91. // the inner, private unknown implementation is for the aggregator
  92. // to control the lifetime of this object, and for those cases where
  93. // this object isn't aggregated.
  94. class CPrivateUnknownObject : public IUnknown {
  95. public:
  96. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut);
  97. STDMETHOD_(ULONG, AddRef)(void);
  98. STDMETHOD_(ULONG, Release)(void);
  99. // constructor is remarkably trivial
  100. //
  101. CPrivateUnknownObject() : m_cRef(1) {}
  102. private:
  103. CUnknownObject *m_pMainUnknown();
  104. ULONG m_cRef;
  105. } m_UnkPrivate;
  106. // so they can reference themselves in CUnknownObject from pMainUnknown()
  107. friend class CPrivateUnknownObject;
  108. };
  109. #endif // _UNKNOWN_H_