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.

425 lines
15 KiB

  1. /********************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. ScriptWrapper_ClientSide.cpp
  5. Abstract:
  6. File for implementation of CPCHScriptWrapper_ClientSideRoot class,
  7. a generic wrapper for remoting scripting engines.
  8. Revision History:
  9. Davide Massarenti created 03/28/2000
  10. ********************************************************************/
  11. #include "stdafx.h"
  12. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  13. bool CPCHScriptWrapper_ClientSideRoot::NamedItem::operator==( /*[in]*/ LPCOLESTR szKey ) const
  14. {
  15. return MPC::StrICmp( m_bstrName, szKey ) == 0;
  16. }
  17. bool CPCHScriptWrapper_ClientSideRoot::TypeLibItem::operator==( /*[in]*/ REFGUID rguidTypeLib ) const
  18. {
  19. return ::IsEqualGUID( m_guidTypeLib, rguidTypeLib ) == TRUE;
  20. }
  21. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  22. CPCHScriptWrapper_ClientSideRoot::CPCHScriptWrapper_ClientSideRoot()
  23. {
  24. m_pWrappedCLSID = NULL; // const CLSID* m_pWrappedCLSID;
  25. // NamedList m_lstNamed;
  26. // TypeLibList m_lstTypeLib;
  27. m_ss = SCRIPTSTATE_UNINITIALIZED; // SCRIPTSTATE m_ss;
  28. // CComPtr<IActiveScriptSite> m_Browser;
  29. // CComPtr<IPCHActiveScript> m_Script;
  30. }
  31. CPCHScriptWrapper_ClientSideRoot::~CPCHScriptWrapper_ClientSideRoot()
  32. {
  33. }
  34. HRESULT CPCHScriptWrapper_ClientSideRoot::FinalConstructInner( /*[in]*/ const CLSID* pWrappedCLSID )
  35. {
  36. m_pWrappedCLSID = pWrappedCLSID;
  37. return S_OK;
  38. }
  39. void CPCHScriptWrapper_ClientSideRoot::FinalRelease()
  40. {
  41. m_Browser.Release();
  42. m_Script .Release();
  43. }
  44. ////////////////////////////////////////////////////////////////////////////////
  45. //
  46. // IActiveScript
  47. //
  48. ////////////////////////////////////////////////////////////////////////////////
  49. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::SetScriptSite( /*[in]*/ IActiveScriptSite* pass )
  50. {
  51. m_Browser = pass;
  52. return S_OK;
  53. }
  54. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::GetScriptSite( /*[in ]*/ REFIID riid ,
  55. /*[out]*/ void* *ppvObject )
  56. {
  57. if(m_Browser == NULL) return E_FAIL;
  58. return m_Browser->QueryInterface( riid, ppvObject );
  59. }
  60. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::SetScriptState( /*[in] */ SCRIPTSTATE ss )
  61. {
  62. m_ss = ss;
  63. if(m_Script) return m_Script->Remote_SetScriptState( ss );
  64. return S_OK;
  65. }
  66. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::GetScriptState( /*[out]*/ SCRIPTSTATE *pssState )
  67. {
  68. HRESULT hr = S_OK;
  69. if(m_Script)
  70. {
  71. hr = m_Script->Remote_GetScriptState( &m_ss );
  72. }
  73. if(pssState) *pssState = m_ss;
  74. return hr;
  75. }
  76. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Close( void )
  77. {
  78. if(m_Script) return m_Script->Remote_Close();
  79. return S_OK;
  80. }
  81. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::AddNamedItem( /*[in]*/ LPCOLESTR pstrName ,
  82. /*[in]*/ DWORD dwFlags )
  83. {
  84. NamedIter it;
  85. it = std::find( m_lstNamed.begin(), m_lstNamed.end(), pstrName );
  86. if(it == m_lstNamed.end())
  87. {
  88. it = m_lstNamed.insert( m_lstNamed.end() );
  89. it->m_bstrName = pstrName;
  90. }
  91. it->m_dwFlags = dwFlags;
  92. if(m_Script) return m_Script->Remote_AddNamedItem( CComBSTR( pstrName ), dwFlags );
  93. return S_OK;
  94. }
  95. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::AddTypeLib( /*[in]*/ REFGUID rguidTypeLib ,
  96. /*[in]*/ DWORD dwMajor ,
  97. /*[in]*/ DWORD dwMinor ,
  98. /*[in]*/ DWORD dwFlags )
  99. {
  100. TypeLibIter it;
  101. it = std::find( m_lstTypeLib.begin(), m_lstTypeLib.end(), rguidTypeLib );
  102. if(it == m_lstTypeLib.end())
  103. {
  104. it = m_lstTypeLib.insert( m_lstTypeLib.end() );
  105. it->m_guidTypeLib = rguidTypeLib;
  106. }
  107. it->m_dwMajor = dwMajor;
  108. it->m_dwMinor = dwMinor;
  109. it->m_dwFlags = dwFlags;
  110. if(m_Script) return m_Script->Remote_AddTypeLib( CComBSTR( rguidTypeLib ), dwMajor, dwMinor, dwFlags );
  111. return S_OK;
  112. }
  113. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::GetScriptDispatch( /*[in ]*/ LPCOLESTR pstrItemName ,
  114. /*[out]*/ IDispatch* *ppdisp )
  115. {
  116. if(m_Script == NULL) return E_FAIL;
  117. return m_Script->Remote_GetScriptDispatch( CComBSTR( pstrItemName ), ppdisp );
  118. }
  119. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::GetCurrentScriptThreadID( /*[out]*/ SCRIPTTHREADID *pstidThread )
  120. {
  121. if(m_Script == NULL) return E_FAIL;
  122. return m_Script->Remote_GetCurrentScriptThreadID( pstidThread );
  123. }
  124. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::GetScriptThreadID( /*[in ]*/ DWORD dwWin32ThreadId ,
  125. /*[out]*/ SCRIPTTHREADID *pstidThread )
  126. {
  127. if(m_Script == NULL) return E_FAIL;
  128. return m_Script->Remote_GetScriptThreadID( dwWin32ThreadId, pstidThread );
  129. }
  130. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::GetScriptThreadState( /*[in ]*/ SCRIPTTHREADID stidThread ,
  131. /*[out]*/ SCRIPTTHREADSTATE *pstsState )
  132. {
  133. if(m_Script == NULL) return E_FAIL;
  134. return m_Script->Remote_GetScriptThreadState( stidThread, pstsState );
  135. }
  136. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::InterruptScriptThread( /*[in]*/ SCRIPTTHREADID stidThread ,
  137. /*[in]*/ const EXCEPINFO* pexcepinfo ,
  138. /*[in]*/ DWORD dwFlags )
  139. {
  140. if(m_Script == NULL) return E_FAIL;
  141. return m_Script->Remote_InterruptScriptThread( stidThread, dwFlags );
  142. }
  143. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Clone( /*[out]*/ IActiveScript* *ppscript )
  144. {
  145. return E_NOTIMPL;
  146. }
  147. ////////////////////////////////////////////////////////////////////////////////
  148. //
  149. // IActiveScriptParse
  150. //
  151. ////////////////////////////////////////////////////////////////////////////////
  152. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::InitNew( void )
  153. {
  154. m_lstNamed .clear();
  155. m_lstTypeLib.clear();
  156. m_ss = SCRIPTSTATE_INITIALIZED;
  157. m_Browser.Release();
  158. m_Script .Release();
  159. return S_OK;
  160. }
  161. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::AddScriptlet( /*[in ]*/ LPCOLESTR pstrDefaultName ,
  162. /*[in ]*/ LPCOLESTR pstrCode ,
  163. /*[in ]*/ LPCOLESTR pstrItemName ,
  164. /*[in ]*/ LPCOLESTR pstrSubItemName ,
  165. /*[in ]*/ LPCOLESTR pstrEventName ,
  166. /*[in ]*/ LPCOLESTR pstrDelimiter ,
  167. /*[in ]*/ DWORD_PTR dwSourceContextCookie ,
  168. /*[in ]*/ ULONG ulStartingLineNumber ,
  169. /*[in ]*/ DWORD dwFlags ,
  170. /*[out]*/ BSTR *pbstrName ,
  171. /*[out]*/ EXCEPINFO *pexcepinfo )
  172. {
  173. return E_NOTIMPL;
  174. }
  175. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::ParseScriptText( /*[in ]*/ LPCOLESTR pstrCode ,
  176. /*[in ]*/ LPCOLESTR pstrItemName ,
  177. /*[in ]*/ IUnknown* punkContext ,
  178. /*[in ]*/ LPCOLESTR pstrDelimiter ,
  179. /*[in ]*/ DWORD_PTR dwSourceContextCookie ,
  180. /*[in ]*/ ULONG ulStartingLineNumber ,
  181. /*[in ]*/ DWORD dwFlags ,
  182. /*[out]*/ VARIANT *pvarResult ,
  183. /*[out]*/ EXCEPINFO *pexcepinfo )
  184. {
  185. __HCP_FUNC_ENTRY( "CPCHScriptWrapper_ClientSideRoot::ParseScriptText" );
  186. HRESULT hr;
  187. CComPtr<IUnknown> unk;
  188. CComBSTR bstrURL;
  189. //
  190. // Extract the URL of the page containing the script.
  191. //
  192. {
  193. CComQIPtr<IServiceProvider> sp = m_Browser;
  194. if(sp)
  195. {
  196. CComPtr<IHTMLDocument2> doc;
  197. if(SUCCEEDED(sp->QueryService( CLSID_HTMLDocument, IID_IHTMLDocument2, (void**)&doc )) && doc)
  198. {
  199. (void)doc->get_URL( &bstrURL );
  200. }
  201. }
  202. }
  203. __MPC_EXIT_IF_METHOD_FAILS(hr, CPCHHelpCenterExternal::s_GLOBAL->CreateScriptWrapper( *m_pWrappedCLSID, (BSTR)pstrCode, bstrURL, &unk ));
  204. if(unk == NULL)
  205. {
  206. __MPC_SET_ERROR_AND_EXIT(hr, E_NOINTERFACE);
  207. }
  208. //
  209. // At this point, we have a valid script host for the vendor associated with the URL.
  210. //
  211. // Beware, IE reuses the IActiveScript object for all the script island in the same page,
  212. // but our engine is tied to only one vendor, so this could be a problem IF we have
  213. // script snippets from different vendors in the same page.
  214. //
  215. // Fortunately, we also check that the URL matches the vendor, it cannot happen that
  216. // the URL gets resolved as belonging to two vendors.
  217. //
  218. // In brief, thanks to the URL/vendor cross-checking, it cannot happen that we reach
  219. // this point in the code for two different vendors.
  220. //
  221. if(m_Script == NULL)
  222. {
  223. NamedIterConst itNamed;
  224. TypeLibIterConst itTypeLib;
  225. __MPC_EXIT_IF_METHOD_FAILS(hr, unk->QueryInterface( IID_IPCHActiveScript, (void**)&m_Script ));
  226. ////////////////////
  227. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Script->Remote_InitNew());
  228. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Script->Remote_SetScriptSite( (IPCHActiveScriptSite*)this ));
  229. __MPC_EXIT_IF_METHOD_FAILS(hr, SetScriptState( SCRIPTSTATE_STARTED ));
  230. for(itNamed = m_lstNamed.begin(); itNamed != m_lstNamed.end(); itNamed++)
  231. {
  232. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Script->Remote_AddNamedItem( itNamed->m_bstrName,
  233. itNamed->m_dwFlags ));
  234. }
  235. for(itTypeLib = m_lstTypeLib.begin(); itTypeLib != m_lstTypeLib.end(); itTypeLib++)
  236. {
  237. __MPC_EXIT_IF_METHOD_FAILS(hr, m_Script->Remote_AddTypeLib( CComBSTR( itTypeLib->m_guidTypeLib ),
  238. itTypeLib->m_dwMajor ,
  239. itTypeLib->m_dwMinor ,
  240. itTypeLib->m_dwFlags ));
  241. }
  242. }
  243. hr = m_Script->Remote_ParseScriptText( CComBSTR( pstrCode ),
  244. CComBSTR( pstrItemName ),
  245. punkContext ,
  246. CComBSTR( pstrDelimiter ),
  247. dwSourceContextCookie ,
  248. ulStartingLineNumber ,
  249. dwFlags ,
  250. pvarResult );
  251. __HCP_FUNC_CLEANUP;
  252. __HCP_FUNC_EXIT(hr);
  253. }
  254. ////////////////////////////////////////////////////////////////////////////////
  255. //
  256. // IPCHActiveScriptSite
  257. //
  258. ////////////////////////////////////////////////////////////////////////////////
  259. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Remote_GetLCID( /*[out]*/ BSTR *plcid )
  260. {
  261. HRESULT hr;
  262. CComBSTR bstr;
  263. CComVariant v;
  264. LCID lcid;
  265. if(m_Browser == NULL) return E_FAIL;
  266. if(FAILED(hr = m_Browser->GetLCID( &lcid ))) return hr;
  267. v = (long)lcid; v.ChangeType( VT_BSTR ); bstr = v.bstrVal;
  268. if(plcid) *plcid = bstr.Detach();
  269. return S_OK;
  270. }
  271. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Remote_GetItemInfo( /*[in ]*/ BSTR bstrName ,
  272. /*[in ]*/ DWORD dwReturnMask ,
  273. /*[out]*/ IUnknown* *ppiunkItem ,
  274. /*[out]*/ ITypeInfo* *ppti )
  275. {
  276. HRESULT hr;
  277. CComPtr<IUnknown> unk;
  278. CComPtr<ITypeInfo> pti;
  279. if(m_Browser == NULL) return E_FAIL;
  280. if(FAILED(hr = m_Browser->GetItemInfo( bstrName, dwReturnMask,
  281. (dwReturnMask & SCRIPTINFO_IUNKNOWN ) ? &unk : NULL,
  282. (dwReturnMask & SCRIPTINFO_ITYPEINFO) ? &pti : NULL ))) return hr;
  283. if(ppiunkItem)
  284. {
  285. if(FAILED(hr = CPCHDispatchWrapper::CreateInstance( unk, ppiunkItem ))) return hr;
  286. }
  287. if(ppti)
  288. {
  289. *ppti = pti.Detach();
  290. }
  291. return S_OK;
  292. }
  293. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Remote_GetDocVersionString( /*[out]*/ BSTR *pbstrVersion )
  294. {
  295. if(m_Browser == NULL) return E_FAIL;
  296. return m_Browser->GetDocVersionString( pbstrVersion );
  297. }
  298. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Remote_OnScriptTerminate( /*[in]*/ VARIANT* pvarResult )
  299. {
  300. if(m_Browser == NULL) return E_FAIL;
  301. return m_Browser->OnScriptTerminate( pvarResult, NULL );
  302. }
  303. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Remote_OnStateChange( /*[in]*/ SCRIPTSTATE ssScriptState )
  304. {
  305. if(m_Browser == NULL) return E_FAIL;
  306. return m_Browser->OnStateChange( ssScriptState );
  307. }
  308. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Remote_OnScriptError( /*[in]*/ IUnknown* pscripterror )
  309. {
  310. CComQIPtr<IActiveScriptError> scripterror( pscripterror );
  311. if(m_Browser == NULL) return E_FAIL;
  312. return m_Browser->OnScriptError( scripterror );
  313. }
  314. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Remote_OnEnterScript( void )
  315. {
  316. if(m_Browser == NULL) return E_FAIL;
  317. return m_Browser->OnEnterScript();
  318. };
  319. STDMETHODIMP CPCHScriptWrapper_ClientSideRoot::Remote_OnLeaveScript( void )
  320. {
  321. if(m_Browser == NULL) return E_FAIL;
  322. return m_Browser->OnLeaveScript();
  323. }