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.

157 lines
5.4 KiB

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