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.

355 lines
8.7 KiB

  1. // MarshalableTI.h : Declaration of the CMarshalableTI
  2. #ifndef __MARSHALABLETI_H_
  3. #define __MARSHALABLETI_H_
  4. #include "mslablti.h"
  5. #include "resource.h" // main symbols
  6. // ATL doesn't support multiple LCID's at the same time
  7. // Whatever LCID is queried for first is the one that is used.
  8. class CComTypeInfoHolder2
  9. {
  10. // Should be 'protected' but can cause compiler to generate fat code.
  11. public:
  12. const GUID* m_pguid;
  13. const GUID* m_plibid;
  14. WORD m_wMajor;
  15. WORD m_wMinor;
  16. ITypeInfo* m_pInfo;
  17. long m_dwRef;
  18. struct stringdispid
  19. {
  20. CComBSTR bstr;
  21. int nLen;
  22. DISPID id;
  23. };
  24. stringdispid* m_pMap;
  25. int m_nCount;
  26. ~CComTypeInfoHolder2()
  27. {
  28. if (m_pInfo != NULL)
  29. m_pInfo->Release();
  30. m_pInfo = NULL;
  31. delete [] m_pMap;
  32. m_pMap = NULL;
  33. }
  34. public:
  35. HRESULT GetTI(LCID lcid, ITypeInfo** ppInfo)
  36. {
  37. HRESULT hr = S_OK;
  38. if (m_pInfo == NULL)
  39. hr = GetTI(lcid);
  40. *ppInfo = m_pInfo;
  41. if (m_pInfo != NULL)
  42. {
  43. m_pInfo->AddRef();
  44. hr = S_OK;
  45. }
  46. return hr;
  47. }
  48. HRESULT GetTI(LCID lcid);
  49. HRESULT EnsureTI(LCID lcid)
  50. {
  51. HRESULT hr = S_OK;
  52. if (m_pInfo == NULL)
  53. hr = GetTI(lcid);
  54. return hr;
  55. }
  56. HRESULT GetTypeInfo(UINT /* itinfo */, LCID lcid, ITypeInfo** pptinfo)
  57. {
  58. HRESULT hRes = E_POINTER;
  59. if (pptinfo != NULL)
  60. hRes = GetTI(lcid, pptinfo);
  61. return hRes;
  62. }
  63. HRESULT GetIDsOfNames(REFIID /* riid */, LPOLESTR* rgszNames, UINT cNames,
  64. LCID lcid, DISPID* rgdispid)
  65. {
  66. HRESULT hRes = EnsureTI(lcid);
  67. if (m_pInfo != NULL)
  68. {
  69. for (int i=0; i<(int)cNames; i++)
  70. {
  71. int n = ocslen(rgszNames[i]);
  72. for (int j=m_nCount-1; j>=0; j--)
  73. {
  74. if ((n == m_pMap[j].nLen) &&
  75. (memcmp(m_pMap[j].bstr, rgszNames[i], m_pMap[j].nLen * sizeof(OLECHAR)) == 0))
  76. {
  77. rgdispid[i] = m_pMap[j].id;
  78. break;
  79. }
  80. }
  81. if (j < 0)
  82. {
  83. hRes = m_pInfo->GetIDsOfNames(rgszNames + i, 1, &rgdispid[i]);
  84. if (FAILED(hRes))
  85. break;
  86. }
  87. }
  88. }
  89. return hRes;
  90. }
  91. HRESULT Invoke(IDispatch* p, DISPID dispidMember, REFIID /* riid */,
  92. LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
  93. EXCEPINFO* pexcepinfo, UINT* puArgErr)
  94. {
  95. HRESULT hRes = EnsureTI(lcid);
  96. if (m_pInfo != NULL)
  97. hRes = m_pInfo->Invoke(p, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
  98. return hRes;
  99. }
  100. HRESULT LoadNameCache(ITypeInfo* pTypeInfo)
  101. {
  102. TYPEATTR* pta;
  103. HRESULT hr = pTypeInfo->GetTypeAttr(&pta);
  104. if (SUCCEEDED(hr))
  105. {
  106. m_nCount = pta->cFuncs;
  107. m_pMap = m_nCount == 0 ? 0 : new stringdispid[m_nCount];
  108. for (int i=0; i<m_nCount; i++)
  109. {
  110. FUNCDESC* pfd;
  111. if (SUCCEEDED(pTypeInfo->GetFuncDesc(i, &pfd)))
  112. {
  113. CComBSTR bstrName;
  114. if (SUCCEEDED(pTypeInfo->GetDocumentation(pfd->memid, &bstrName, NULL, NULL, NULL)))
  115. {
  116. m_pMap[i].bstr.Attach(bstrName.Detach());
  117. m_pMap[i].nLen = SysStringLen(m_pMap[i].bstr);
  118. m_pMap[i].id = pfd->memid;
  119. }
  120. pTypeInfo->ReleaseFuncDesc(pfd);
  121. }
  122. }
  123. pTypeInfo->ReleaseTypeAttr(pta);
  124. }
  125. return S_OK;
  126. }
  127. };
  128. inline HRESULT CComTypeInfoHolder2::GetTI(LCID lcid)
  129. {
  130. //If this assert occurs then most likely didn't initialize properly
  131. ATLASSERT(m_plibid != NULL && m_pguid != NULL);
  132. ATLASSERT(!InlineIsEqualGUID(*m_plibid, GUID_NULL) && "Did you forget to pass the LIBID to CComModule::Init?");
  133. if (m_pInfo != NULL)
  134. return S_OK;
  135. HRESULT hRes = E_FAIL;
  136. EnterCriticalSection(&_Module.m_csTypeInfoHolder);
  137. if (m_pInfo == NULL)
  138. {
  139. ITypeLib* pTypeLib;
  140. hRes = LoadRegTypeLib(*m_plibid, m_wMajor, m_wMinor, lcid, &pTypeLib);
  141. if (SUCCEEDED(hRes))
  142. {
  143. CComPtr<ITypeInfo> spTypeInfo;
  144. hRes = pTypeLib->GetTypeInfoOfGuid(*m_pguid, &spTypeInfo);
  145. if (SUCCEEDED(hRes))
  146. {
  147. CComPtr<ITypeInfo> spInfo(spTypeInfo);
  148. CComPtr<ITypeInfo2> spTypeInfo2;
  149. if (SUCCEEDED(spTypeInfo->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&spTypeInfo2))))
  150. spInfo = spTypeInfo2;
  151. LoadNameCache(spInfo);
  152. m_pInfo = spInfo.Detach();
  153. }
  154. pTypeLib->Release();
  155. }
  156. }
  157. LeaveCriticalSection(&_Module.m_csTypeInfoHolder);
  158. return hRes;
  159. }
  160. /////////////////////////////////////////////////////////////////////////////
  161. // CMarshalableTI
  162. class ATL_NO_VTABLE CMarshalableTI :
  163. public CComObjectRootEx<CComSingleThreadModel>,
  164. public CComCoClass<CMarshalableTI, &CLSID_MarshalableTI>,
  165. public IMarshalableTI,
  166. public IMarshal,
  167. public ITypeInfo
  168. {
  169. private:
  170. CComTypeInfoHolder2 m_TIHolder;
  171. GUID m_guid;
  172. GUID m_libid;
  173. LCID m_lcid;
  174. bool m_bCreated;
  175. public:
  176. DECLARE_REGISTRY_RESOURCEID(IDR_MSLABLTI)
  177. DECLARE_NOT_AGGREGATABLE(CMarshalableTI)
  178. DECLARE_PROTECT_FINAL_CONSTRUCT()
  179. BEGIN_COM_MAP(CMarshalableTI)
  180. COM_INTERFACE_ENTRY(IMarshalableTI)
  181. COM_INTERFACE_ENTRY(IMarshal)
  182. COM_INTERFACE_ENTRY(ITypeInfo)
  183. END_COM_MAP()
  184. HRESULT FinalConstruct();
  185. /////////////////////////////////////////////////////////////////////////////////
  186. // IMarshalableTI methods
  187. STDMETHOD(Create)(/*[in]*/ REFIID clsid,
  188. /*[in]*/ REFIID iidLib,
  189. /*[in]*/ LCID lcid,
  190. /*[in]*/ WORD dwMajorVer,
  191. /*[in]*/ WORD dwMinorVer);
  192. /////////////////////////////////////////////////////////////////////////////////
  193. // IMarshal methods
  194. STDMETHOD(GetUnmarshalClass)(
  195. /* [in] */ REFIID riid,
  196. /* [unique][in] */ void *pv,
  197. /* [in] */ DWORD dwDestContext,
  198. /* [unique][in] */ void *pvDestContext,
  199. /* [in] */ DWORD mshlflags,
  200. /* [out] */ CLSID *pCid);
  201. STDMETHOD(GetMarshalSizeMax)(
  202. /* [in] */ REFIID riid,
  203. /* [unique][in] */ void *pv,
  204. /* [in] */ DWORD dwDestContext,
  205. /* [unique][in] */ void *pvDestContext,
  206. /* [in] */ DWORD mshlflags,
  207. /* [out] */ DWORD *pSize);
  208. STDMETHOD(MarshalInterface)(
  209. /* [unique][in] */ IStream *pStm,
  210. /* [in] */ REFIID riid,
  211. /* [unique][in] */ void *pv,
  212. /* [in] */ DWORD dwDestContext,
  213. /* [unique][in] */ void *pvDestContext,
  214. /* [in] */ DWORD mshlflags);
  215. STDMETHOD(UnmarshalInterface)(
  216. /* [unique][in] */ IStream *pStm,
  217. /* [in] */ REFIID riid,
  218. /* [out] */ void **ppv);
  219. STDMETHOD(ReleaseMarshalData)(
  220. /* [unique][in] */ IStream *pStm);
  221. STDMETHOD(DisconnectObject)(
  222. /* [in] */ DWORD dwReserved);
  223. /////////////////////////////////////////////////////////////////////////////////
  224. // ITypeInfo methods
  225. STDMETHOD(GetTypeAttr)(
  226. TYPEATTR ** ppTypeAttr);
  227. STDMETHOD(GetTypeComp)(
  228. ITypeComp ** ppTComp);
  229. STDMETHOD(GetFuncDesc)(
  230. UINT index,
  231. FUNCDESC ** ppFuncDesc);
  232. STDMETHOD(GetVarDesc)(
  233. UINT index,
  234. VARDESC ** ppVarDesc);
  235. STDMETHOD(GetNames)(
  236. MEMBERID memid,
  237. BSTR * rgBstrNames,
  238. UINT cMaxNames,
  239. UINT * pcNames);
  240. STDMETHOD(GetRefTypeOfImplType)(
  241. UINT index,
  242. HREFTYPE * pRefType);
  243. STDMETHOD(GetImplTypeFlags)(
  244. UINT index,
  245. INT * pImplTypeFlags);
  246. STDMETHOD(GetIDsOfNames)(
  247. LPOLESTR * rgszNames,
  248. UINT cNames,
  249. MEMBERID * pMemId);
  250. STDMETHOD(Invoke)(
  251. PVOID pvInstance,
  252. MEMBERID memid,
  253. WORD wFlags,
  254. DISPPARAMS * pDispParams,
  255. VARIANT * pVarResult,
  256. EXCEPINFO * pExcepInfo,
  257. UINT * puArgErr);
  258. STDMETHOD(GetDocumentation)(
  259. MEMBERID memid,
  260. BSTR * pBstrName,
  261. BSTR * pBstrDocString,
  262. DWORD * pdwHelpContext,
  263. BSTR * pBstrHelpFile);
  264. STDMETHOD(GetDllEntry)(
  265. MEMBERID memid,
  266. INVOKEKIND invKind,
  267. BSTR * pBstrDllName,
  268. BSTR * pBstrName,
  269. WORD * pwOrdinal);
  270. STDMETHOD(GetRefTypeInfo)(
  271. HREFTYPE hRefType,
  272. ITypeInfo ** ppTInfo);
  273. STDMETHOD(AddressOfMember)(
  274. MEMBERID memid,
  275. INVOKEKIND invKind,
  276. PVOID * ppv);
  277. STDMETHOD(CreateInstance)(
  278. IUnknown * pUnkOuter,
  279. REFIID riid,
  280. PVOID * ppvObj);
  281. STDMETHOD(GetMops)(
  282. MEMBERID memid,
  283. BSTR * pBstrMops);
  284. STDMETHOD(GetContainingTypeLib)(
  285. ITypeLib ** ppTLib,
  286. UINT * pIndex);
  287. STDMETHOD_(void, ReleaseTypeAttr)(
  288. TYPEATTR * pTypeAttr);
  289. STDMETHOD_(void, ReleaseFuncDesc)(
  290. FUNCDESC * pFuncDesc);
  291. STDMETHOD_(void, ReleaseVarDesc)(
  292. VARDESC * pVarDesc);
  293. private:
  294. HRESULT _GetClassInfo(ITypeInfo** ppTI);
  295. };
  296. #endif //__MARSHALABLETI_H_