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.

239 lines
7.4 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: cdispmgr.cxx
  7. //
  8. // Contents: The dispatch manager -- a class to manage
  9. // multiple IDispatch-callable interfaces.
  10. //
  11. // History: ??-???-?? KrishnaG created
  12. // 07-Sep-97 t-blakej Commented, cleaned up, made
  13. // independent of ADSI.
  14. //
  15. //----------------------------------------------------------------------------
  16. //
  17. // Dispatch manager description:
  18. //
  19. //
  20. // The dispatch manager is a way to invoke methods on an object that has
  21. // more than one COM interface. The regular GetIDsOfNames and Invoke
  22. // methods assume only a single ITypeInfo to look up and call names from;
  23. // if an object has more than one interface, it has multiple ITypeInfo's,
  24. // and it has to explicitly check each one. The dispatch manager implements
  25. // the IDispatch methods, and keeps track of as many ITypeInfos as necessary.
  26. //
  27. // To use the dispatch manager, an object should store a pointer to a
  28. // CAggregateeDispMgr object and delegate all IDispatch calls to it, or perhaps
  29. // inherit from it directly. The method
  30. //
  31. // HRESULT CAggregateeDispMgr::LoadTypeInfoEntry(
  32. // REFIID libid, REFIID iid, void *pIntf, DISPID SpecialId)
  33. //
  34. // is used to load the type information for the object into the dispatch
  35. // manager. The arguments to this method are:
  36. //
  37. // REFIID libid - IID of the type library to load from
  38. // REFIID iid - IID of the interface to load
  39. // void *pIntf - pointer to the interface on the containing
  40. // object
  41. // DISPID SpecialId - DISPID_REGULAR for most things (see below);
  42. // DISPID_VALUE for interfaces which implement
  43. // the containing object's "value" property;
  44. // DISPID_NEWENUM for interfaces which implement
  45. // the containing object's "NewEnum" method
  46. //
  47. // DISPID_REGULAR is defined to be 1 by all ADSI providers, but not in
  48. // any top-level include file. So non-ADSI users of the dispatch manager will
  49. // probably have to define it explicitly.
  50. //
  51. // The LoadTypeInfoEntry method should be called at constructor time of
  52. // the containing object. After all the type information is loaded, the
  53. // dispatch manager can start servicing GetIDsOfNames and Invoke calls.
  54. //
  55. //
  56. // For ADSI, there are two other calls to load information into the dispatch
  57. // manager:
  58. //
  59. // void CAggregateeDispMgr::RegisterPropertyCache(IPropertyCache *pPropertyCache);
  60. // void CAggregateeDispMgr::RegisterBaseDispatchPtr(IDispatch *pDispatch);
  61. //
  62. // The first method registers a property cache of the containing object;
  63. // this is used in the ADSI providers to cache attributes of a directory
  64. // server object. See iprops.hxx for more information.
  65. //
  66. // The second method is a hack used to get around a lack of inheritance.
  67. // If an object A implements IDispatch and some other dual interfaces,
  68. // and an object B derives from A and also implements IDispatch and some
  69. // other dual interfaces, this method can be used in object B to use A's
  70. // dispatch manager as a "backup" to its own. This way B doesn't have to
  71. // load the type information about the interfaces it inherits from A.
  72. // (Also, if A has an ADSI property cache, then callers of B's IDispatch
  73. // methods can get at the underlying property cache.)
  74. //
  75. // The function
  76. //
  77. // void FreeTypeInfoTable();
  78. //
  79. // should be called at global destructor or library-unload time. Currently,
  80. // all the ADSI libraries do it separately.
  81. //
  82. //
  83. // The DISPIDs returned by GetIDsOfNames are 32 bit values laid out
  84. // as follows:
  85. //
  86. // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
  87. // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  88. // +-+-------------+---------------+-------------------------------+
  89. // |X| DispMgrId | TypeInfoId | DispId |
  90. // +-+-------------+---------------+-------------------------------+
  91. //
  92. // where
  93. //
  94. // X - is reserved and never set. This would turn the value negative
  95. // (which would overlap with some Automation-reserved DISPIDs.)
  96. //
  97. // DispMgrId - identifies the dispatch manager (used when stringing
  98. // dispatch managers together via RegisterBaseDispatchPtr).
  99. //
  100. // TypeInfoId - uniquely identifies the interface within this
  101. // dispatch manager.
  102. //
  103. // DispId - uniquely identifies the name within the interface.
  104. //
  105. // So if an object uses the dispatch manager, it shouldn't try to only use
  106. // it for just GetIDsOfNames or just Invoke, since the DISPIDs returned are
  107. // not necessarily the ones in the type library.
  108. //
  109. //////////////////////////////////////////////////////////////////////////////
  110. /*
  111. // Forward declarations:
  112. struct IPropertyCache;
  113. typedef struct _typeinfoentry
  114. {
  115. LONG TypeInfoId;
  116. void *ptypeinfo;
  117. void *pInterfacePointer;
  118. struct _typeinfoentry *pNext;
  119. } TYPEINFOENTRY, *PTYPEINFOENTRY;
  120. */
  121. class CAggregateeDispMgr
  122. {
  123. public:
  124. CAggregateeDispMgr::CAggregateeDispMgr();
  125. CAggregateeDispMgr::~CAggregateeDispMgr();
  126. //
  127. // The IDispatch methods are the main interface of the Dispatch Manager.
  128. //
  129. STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR* pctinfo);
  130. STDMETHOD(GetTypeInfo)(THIS_ UINT itinfo, LCID lcid, ITypeInfo **pptinfo);
  131. STDMETHOD(GetIDsOfNames)(THIS_ REFIID riid, LPWSTR *rgszNames,
  132. UINT cNames, LCID lcid, DISPID *rgdispid);
  133. STDMETHOD(Invoke)(THIS_ DISPID dispidMember, REFIID riid, LCID lcid,
  134. WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult,
  135. EXCEPINFO *pexcepinfo, UINT *puArgErr);
  136. //
  137. // Methods for initializing the dispatch manager.
  138. //
  139. void
  140. CAggregateeDispMgr::RegisterPropertyCache(IPropertyCache* pPropertyCache);
  141. HRESULT
  142. CAggregateeDispMgr::LoadTypeInfoEntry(
  143. REFIID libid,
  144. REFIID iid,
  145. void * pIntf,
  146. DISPID SpecialId
  147. );
  148. HRESULT
  149. CAggregateeDispMgr::InitializeDispMgr(
  150. DWORD dwExtensionID
  151. );
  152. private:
  153. void *
  154. CAggregateeDispMgr::getInterfacePtr(LONG TypeInfoId);
  155. ITypeInfo *
  156. CAggregateeDispMgr::getTypeInfo(LONG TypeInfoId);
  157. PTYPEINFOENTRY
  158. CAggregateeDispMgr::FindTypeInfoEntry(LONG TypeInfoId);
  159. HRESULT
  160. CAggregateeDispMgr::AddTypeInfo(void FAR *ptypeinfo, void * pIntfptr);
  161. STDMETHODIMP
  162. CAggregateeDispMgr::TypeInfoInvoke(DISPID dispidMember, REFIID iid, LCID lcid,
  163. unsigned short wFlags, DISPPARAMS FAR* pdispparams,
  164. VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo,
  165. unsigned int FAR* puArgErr);
  166. HRESULT
  167. CAggregateeDispMgr::MarkAsNewEnum(void *pTypeInfo);
  168. HRESULT
  169. CAggregateeDispMgr::MarkAsItem(void *pTypeInfo);
  170. PTYPEINFOENTRY
  171. CAggregateeDispMgr::FindTypeInfo(void *pTypeInfo);
  172. LONG
  173. CAggregateeDispMgr::gentypeinfoid();
  174. protected:
  175. LONG _dwTypeInfoId;
  176. PTYPEINFOENTRY _pTypeInfoEntry;
  177. PTYPEINFOENTRY _pDispidNewEnum;
  178. PTYPEINFOENTRY _pDispidValue;
  179. IPropertyCache *_pPropertyCache;
  180. LONG _dwPropCacheID;
  181. DWORD _dwExtensionID;
  182. };
  183. #define BAIL_IF_ERROR(hr) if (FAILED(hr)) { goto cleanup; }
  184. // deprecated
  185. HRESULT
  186. AggregateeLoadTypeInfoEntry(
  187. CAggregateeDispMgr * pDispMgr,
  188. REFIID libid,
  189. REFIID iid,
  190. void * pIntf,
  191. DISPID SpecialId
  192. );
  193. void
  194. AggregateeFreeTypeInfoTable();
  195. HRESULT
  196. AggregateeDynamicDispidInvoke(
  197. IPropertyCache * pPropertyCache,
  198. DISPID dispid,
  199. unsigned short wFlags,
  200. DISPPARAMS *pdispparams,
  201. VARIANT * pvarResult
  202. );
  203. BOOL
  204. AggregateeDllCanUnload();