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.

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