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.

181 lines
6.5 KiB

  1. //=--------------------------------------------------------------------------=
  2. // Unknown.H
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // a class definition for an IUnknown super-class that will support
  13. // aggregation.
  14. //
  15. #ifndef _UNKNOWN_H_
  16. #include "Macros.H"
  17. //=--------------------------------------------------------------------------=
  18. // UNKNOWNOBJECTINFO
  19. //
  20. // if you want a simple co-creatable object, with no other guarantees about
  21. // it, then you need to put the following entry in the global table of objects.
  22. // other object types that are more complex, such as automation objects, and
  23. // controls, will also use this information...
  24. //
  25. typedef struct {
  26. const CLSID *rclsid; // CLSID of your object. ONLY USE IF YOU'RE CoCreatable!
  27. LPCSTR pszObjectName; // Name of your object. ONLY USE IF YOU'RE CoCreatable!
  28. LPCSTR pszLabelName; // Registry display name ONLY USE IF YOU'RE CoCreatable!
  29. // for your object
  30. BOOL fApptThreadSafe;
  31. IUnknown *(*pfnCreate)(IUnknown *); // pointer to creation fn. ONLY USE IF YOU'RE CoCreatable!
  32. HRESULT (*pfnPreCreate)(void); // pointer to pre-create fn.
  33. } UNKNOWNOBJECTINFO;
  34. #define NAMEOFOBJECT(index) (((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pszObjectName)
  35. #define LABELOFOBJECT(index) (((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pszLabelName)
  36. #define CLSIDOFOBJECT(index) (*(((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->rclsid))
  37. #define CREATEFNOFOBJECT(index) (((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pfnCreate)
  38. #define ISAPARTMENTMODELTHREADED(index) (((UNKNOWNOBJECTINFO *)(g_ObjectInfo[index].pInfo))->fApptThreadSafe)
  39. #define PRECREATEFNOFOBJECT(index) (((UNKNOWNOBJECTINFO *)(g_ObjectInfo[(index)]).pInfo)->pfnPreCreate)
  40. #ifndef INITOBJECTS
  41. #define DEFINE_UNKNOWNOBJECT(name, clsid, objname, fn) \
  42. extern UNKNOWNOBJECTINFO name##Object \
  43. #define DEFINE_UNKNOWNOBJECT2(name, clsid, objname, lblname, fn, fthreadsafe) \
  44. extern UNKNOWNOBJECTINFO name##Object \
  45. #define DEFINE_UNKNOWNOBJECT3(name, clsid, objname, lblname, precreatefn, fn, fthreadsafe) \
  46. extern UNKNOWNOBJECTINFO name##Object \
  47. #else
  48. #define DEFINE_UNKNOWNOBJECT(name, clsid, objname, fn) \
  49. UNKNOWNOBJECTINFO name##Object = { clsid, objname, NULL, TRUE, fn, NULL } \
  50. #define DEFINE_UNKNOWNOBJECT2(name, clsid, objname, lblname, fn, fthreadsafe) \
  51. UNKNOWNOBJECTINFO name##Object = { clsid, objname, lblname, fthreadsafe, fn, NULL } \
  52. #define DEFINE_UNKNOWNOBJECT3(name, clsid, objname, lblname, precreatefn, fn, fthreadsafe) \
  53. UNKNOWNOBJECTINFO name##Object = { clsid, objname, lblname, fthreadsafe, fn, precreatefn } \
  54. #endif // INITOBJECTS
  55. //=--------------------------------------------------------------------------=
  56. // DECLARE_STANDARD_UNKNOWN
  57. //
  58. // All objects that are going to inherit from CUnknown for their IUnknown
  59. // implementation should put this in their class declaration instead of the
  60. // three IUnknown methods.
  61. //
  62. #define DECLARE_STANDARD_UNKNOWN() \
  63. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut) { \
  64. return ExternalQueryInterface(riid, ppvObjOut); \
  65. } \
  66. STDMETHOD_(ULONG, AddRef)(void) { \
  67. return ExternalAddRef(); \
  68. } \
  69. STDMETHOD_(ULONG, Release)(void) { \
  70. return ExternalRelease(); \
  71. } \
  72. // global variable where we store the current lock count on our DLL. This resides
  73. // in InProcServer.Cpp
  74. //
  75. extern LONG g_cLocks;
  76. //=--------------------------------------------------------------------------=
  77. // this class doesn't inherit from IUnknown since people inheriting from it
  78. // are going to do so, and just delegate their IUnknown calls to the External*
  79. // member functions on this object. the internal private unknown object does
  80. // need to inherit from IUnknown, since it will be used directly as an IUnknown
  81. // object.
  82. //
  83. class CUnknownObject : public CtlNewDelete {
  84. public:
  85. CUnknownObject(IUnknown *pUnkOuter, void *pvInterface)
  86. : m_pvInterface(pvInterface),
  87. m_pUnkOuter((pUnkOuter) ? pUnkOuter : &m_UnkPrivate)
  88. { InterlockedIncrement(&g_cLocks); }
  89. virtual ~CUnknownObject() { InterlockedDecrement(&g_cLocks); }
  90. // these are all protected so that classes that inherit from this can
  91. // at get at them.
  92. //
  93. protected:
  94. // IUnknown methods. these just delegate to the controlling
  95. // unknown.
  96. //
  97. HRESULT ExternalQueryInterface(REFIID riid, void **ppvObjOut) {
  98. return m_pUnkOuter->QueryInterface(riid, ppvObjOut);
  99. }
  100. virtual ULONG ExternalAddRef(void) {
  101. return m_pUnkOuter->AddRef();
  102. }
  103. virtual ULONG ExternalRelease(void) {
  104. return m_pUnkOuter->Release();
  105. }
  106. // people should use this during creation to return their private
  107. // unknown
  108. //
  109. inline IUnknown *PrivateUnknown (void) {
  110. return &m_UnkPrivate;
  111. }
  112. virtual HRESULT InternalQueryInterface(REFIID riid, void **ppvObjOut);
  113. virtual void BeforeDestroyObject(void);
  114. IUnknown *m_pUnkOuter; // outer controlling Unknown
  115. void *m_pvInterface; // the real interface we're working with.
  116. private:
  117. // the inner, private unknown implementation is for the aggregator
  118. // to control the lifetime of this object, and for those cases where
  119. // this object isn't aggregated.
  120. //
  121. class CPrivateUnknownObject : public IUnknown {
  122. public:
  123. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut);
  124. STDMETHOD_(ULONG, AddRef)(void);
  125. STDMETHOD_(ULONG, Release)(void);
  126. // constructor is remarkably trivial
  127. //
  128. CPrivateUnknownObject() : m_cRef(1) {}
  129. private:
  130. CUnknownObject *m_pMainUnknown();
  131. ULONG m_cRef;
  132. } m_UnkPrivate;
  133. // so they can reference themselves in CUnknownObject from pMainUnknown()
  134. //
  135. friend class CPrivateUnknownObject;
  136. // by overriding this, people inheriting from this unknown can implement
  137. // additional interfaces. declared as private here so they have to use their
  138. // own version.
  139. //
  140. };
  141. #define _UNKNOWN_H_
  142. #endif // _UNKNOWN_H_
  143.