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.

500 lines
13 KiB

  1. #include <wininetp.h>
  2. #include <cscpsite.h>
  3. #include <objsafe.h>
  4. #include "jsproxy.h"
  5. #include "utils.h"
  6. /*******************************************************************************
  7. * CScriptSite Functions
  8. ********************************************************************************/
  9. CScriptSite::CScriptSite(CAutoProxy * pAutoProxy)
  10. {
  11. m_refCount = 1;
  12. m_pios = NULL;
  13. m_pasp = NULL;
  14. m_pScriptDispatch = NULL;
  15. m_Scriptdispid = -1;
  16. m_punkJSProxy = NULL;
  17. m_fInitialized = FALSE;
  18. m_dwScriptStartTime = 0;
  19. m_pAutoProxy = pAutoProxy;
  20. }
  21. CScriptSite::~CScriptSite()
  22. {
  23. if (m_fInitialized)
  24. DeInit();
  25. }
  26. STDMETHODIMP CScriptSite::QueryInterface(REFIID riid, PVOID *ppvObject)
  27. {
  28. if (riid == IID_IUnknown)
  29. {
  30. *ppvObject = (LPVOID)(LPUNKNOWN)static_cast<IActiveScriptSite *>(this);
  31. }
  32. else if (riid == IID_IActiveScriptSite)
  33. {
  34. *ppvObject = (LPVOID)static_cast<IActiveScriptSite *>(this);
  35. }
  36. else if (riid == IID_IServiceProvider)
  37. {
  38. *ppvObject = (LPVOID)static_cast<IServiceProvider *>(this);
  39. }
  40. else if (riid == IID_IInternetHostSecurityManager)
  41. {
  42. *ppvObject = (LPVOID)static_cast<IInternetHostSecurityManager *>(this);
  43. }
  44. else if (riid == IID_IActiveScriptSiteInterruptPoll)
  45. {
  46. *ppvObject = (LPVOID)static_cast<IActiveScriptSiteInterruptPoll *>(this);
  47. }
  48. else
  49. {
  50. *ppvObject = 0;
  51. return E_NOINTERFACE;
  52. }
  53. AddRef();
  54. return S_OK;
  55. }
  56. STDMETHODIMP CScriptSite::Init(AUTO_PROXY_HELPER_APIS* pAPHA, LPCSTR szScript)
  57. {
  58. CHAR szClassId[64];
  59. CLSID clsid;
  60. HRESULT hr = S_OK;
  61. BSTR bstrClsID = NULL;
  62. BSTR bstrScriptText = NULL;
  63. OLECHAR * rgwszNames[1] = {L"FindProxyForURL"};
  64. EXCEPINFO exceptinfo;
  65. IObjectSafety * pIObjSafety = NULL;
  66. // pAPHA can be null - it is checked in the autoproxy object!
  67. if (!szScript)
  68. return E_POINTER;
  69. if (m_fInitialized)
  70. return hr;
  71. // CoCreateInstance the JScript engine.
  72. if(!DelayLoad(&g_moduleOle32)
  73. || !DelayLoad(&g_moduleOleAut32))
  74. {
  75. hr = E_OUTOFMEMORY;
  76. goto exit;
  77. }
  78. // Get the class id of the desired language engine
  79. hr = GetScriptEngineClassIDFromName(
  80. "JavaScript",
  81. szClassId,
  82. sizeof(szClassId)
  83. );
  84. if (FAILED(hr)) {
  85. return E_FAIL;
  86. }
  87. //convert CLSID string to clsid
  88. bstrClsID = BSTRFROMANSI(szClassId);
  89. if (!bstrClsID)
  90. goto exit;
  91. hr = DL(CLSIDFromString)(bstrClsID, &clsid);
  92. DL(SysFreeString)(bstrClsID);
  93. if (FAILED(hr))
  94. goto exit;
  95. // Instantiate the script engine
  96. hr = DL(CoCreateInstance)(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void**)&m_pios);
  97. if (FAILED(hr))
  98. goto exit;
  99. // Get the IActiveScriptParse interface, if any
  100. hr = m_pios->QueryInterface(IID_IActiveScriptParse, (void**) &m_pasp);
  101. if (FAILED(hr))
  102. goto exit;
  103. hr = m_pasp->InitNew();
  104. if (FAILED(hr))
  105. goto exit;
  106. // SetScriptSite to this
  107. hr = m_pios->SetScriptSite((IActiveScriptSite *)this);
  108. if (FAILED(hr))
  109. goto exit;
  110. hr = m_pios->SetScriptState(SCRIPTSTATE_INITIALIZED);
  111. //
  112. // Inform the script engine that this host implements
  113. // the IInternetHostSecurityManager interface, which
  114. // is used to prevent the script code from using any
  115. // ActiveX objects.
  116. //
  117. hr = m_pios->QueryInterface(IID_IObjectSafety, (void **)&pIObjSafety);
  118. if (SUCCEEDED(hr) && (pIObjSafety != NULL))
  119. {
  120. pIObjSafety->SetInterfaceSafetyOptions(IID_NULL,
  121. INTERFACE_USES_SECURITY_MANAGER,
  122. INTERFACE_USES_SECURITY_MANAGER);
  123. pIObjSafety->Release();
  124. pIObjSafety = NULL;
  125. }
  126. // AddNamedItem for pUnk and set m_punkJSProxy to pUnk.
  127. // If we added JSProxy to the name space the store away the JSProxy objects punk.
  128. m_punkJSProxy = new CJSProxy;
  129. if( !m_punkJSProxy )
  130. {
  131. hr = E_OUTOFMEMORY;
  132. goto exit;
  133. }
  134. m_punkJSProxy->Init(pAPHA);
  135. hr = m_pios->AddNamedItem(L"JSProxy",SCRIPTITEM_ISVISIBLE | SCRIPTITEM_GLOBALMEMBERS);
  136. if (FAILED(hr))
  137. goto exit;
  138. // Convert the ANSI script text to a bstr.
  139. bstrScriptText = BSTRFROMANSI(szScript);
  140. if (!bstrScriptText)
  141. {
  142. hr = E_OUTOFMEMORY;
  143. goto exit;
  144. }
  145. // Add the script text to the parser
  146. hr = m_pasp->ParseScriptText(
  147. bstrScriptText,
  148. NULL,
  149. NULL,
  150. NULL,
  151. 0,
  152. 0,
  153. SCRIPTTEXT_ISEXPRESSION|SCRIPTTEXT_ISVISIBLE,
  154. NULL,
  155. &exceptinfo);
  156. DL(SysFreeString)(bstrScriptText);
  157. if (FAILED(hr))
  158. goto exit;
  159. m_dwScriptStartTime = GetTickCount();
  160. hr = m_pios->SetScriptState(SCRIPTSTATE_STARTED);
  161. if (FAILED(hr))
  162. goto exit;
  163. // Now get the script dispatch and find the DISPID for the method just added. since this is a single use dll
  164. // I can do this otherwise this would be bad.
  165. hr = m_pios->GetScriptDispatch(NULL,&m_pScriptDispatch);
  166. if (FAILED(hr))
  167. goto exit;
  168. hr = m_pScriptDispatch->GetIDsOfNames(IID_NULL,rgwszNames,1,LOCALE_SYSTEM_DEFAULT,&m_Scriptdispid);
  169. if (FAILED(hr))
  170. goto exit;
  171. m_fInitialized = TRUE;
  172. return hr;
  173. exit: // we come here if something fails - release everything and set to null.
  174. if (m_pasp)
  175. m_pasp->Release();
  176. if (m_pScriptDispatch)
  177. m_pScriptDispatch->Release();
  178. if (m_pios)
  179. {
  180. m_pios->Close();
  181. m_pios->Release();
  182. }
  183. if (m_punkJSProxy)
  184. m_punkJSProxy->Release();
  185. m_pios = NULL;
  186. m_pasp = NULL;
  187. m_pScriptDispatch = NULL;
  188. m_Scriptdispid = -1;
  189. m_punkJSProxy = NULL;
  190. return hr;
  191. }
  192. STDMETHODIMP CScriptSite::DeInit()
  193. {
  194. HRESULT hr = S_OK;
  195. if (m_pasp)
  196. m_pasp->Release();
  197. if (m_pScriptDispatch)
  198. m_pScriptDispatch->Release();
  199. if (m_pios)
  200. {
  201. hr = m_pios->Close();
  202. m_pios->Release();
  203. }
  204. if (m_punkJSProxy)
  205. m_punkJSProxy->Release();
  206. m_pios = NULL;
  207. m_pasp = NULL;
  208. m_pScriptDispatch = NULL;
  209. m_Scriptdispid = -1;
  210. m_fInitialized = FALSE;
  211. return hr;
  212. }
  213. STDMETHODIMP CScriptSite::RunScript(LPCSTR szURL, LPCSTR szHost, LPSTR* result)
  214. {
  215. HRESULT hr = S_OK;
  216. UINT puArgErr = 0;
  217. EXCEPINFO excep;
  218. VARIANT varresult;
  219. DISPPARAMS dispparams;
  220. VARIANT args[2]; // We always call with 2 args!
  221. if (!szURL || !szHost || !result)
  222. return E_POINTER;
  223. if (!m_fInitialized)
  224. return E_UNEXPECTED;
  225. DL(VariantInit)(&varresult);
  226. *result = NULL;
  227. dispparams.cArgs = 2;
  228. DL(VariantInit)(&args[0]);
  229. DL(VariantInit)(&args[1]);
  230. args[0].vt = VT_BSTR;
  231. args[1].vt = VT_BSTR;
  232. args[0].bstrVal = BSTRFROMANSI(szHost);
  233. args[1].bstrVal = BSTRFROMANSI(szURL);
  234. if (args[0].bstrVal==NULL || args[1].bstrVal==NULL)
  235. {
  236. hr = E_OUTOFMEMORY;
  237. goto Cleanup;
  238. }
  239. dispparams.rgvarg = args;
  240. dispparams.cNamedArgs = 0;
  241. dispparams.rgdispidNamedArgs = NULL;
  242. // Call invoke on the stored dispid
  243. hr = m_pScriptDispatch->Invoke(m_Scriptdispid,
  244. IID_NULL,LOCALE_SYSTEM_DEFAULT,
  245. DISPATCH_METHOD,
  246. &dispparams,
  247. &varresult,
  248. &excep,
  249. &puArgErr);
  250. if (FAILED(hr))
  251. goto Cleanup;
  252. // convert result into bstr and return ansi version of the string!
  253. if (varresult.vt == VT_BSTR)
  254. {
  255. MAKE_ANSIPTR_FROMWIDE(rescpy, varresult.bstrVal);
  256. *result = (LPSTR) GlobalAlloc(GPTR|GMEM_ZEROINIT,lstrlen(rescpy)+1);
  257. if (!*result)
  258. {
  259. hr = E_OUTOFMEMORY;
  260. goto Cleanup;
  261. }
  262. lstrcpy(*result,rescpy);
  263. }
  264. else
  265. {
  266. VARIANT resvar;
  267. DL(VariantInit)(&resvar);
  268. hr = DL(VariantChangeType)(&resvar,&varresult,NULL,VT_BSTR);
  269. if (SUCCEEDED(hr))
  270. {
  271. MAKE_ANSIPTR_FROMWIDE(rescpy, resvar.bstrVal);
  272. *result = (LPSTR) GlobalAlloc(GPTR|GMEM_ZEROINIT,lstrlen(rescpy)+1);
  273. if (!*result)
  274. {
  275. hr = E_OUTOFMEMORY;
  276. DL(VariantClear)(&resvar);
  277. goto Cleanup;
  278. }
  279. lstrcpy(*result,rescpy);
  280. }
  281. else
  282. *result = NULL;
  283. DL(VariantClear)(&resvar);
  284. }
  285. Cleanup:
  286. DL(VariantClear)(&varresult);
  287. DL(VariantClear)(&args[0]);
  288. DL(VariantClear)(&args[1]);
  289. return hr;
  290. }
  291. STDMETHODIMP CScriptSite::GetLCID(LCID *plcid)
  292. {
  293. UNREFERENCED_PARAMETER(plcid);
  294. return E_NOTIMPL;
  295. }
  296. STDMETHODIMP CScriptSite::GetItemInfo(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppunkItem, ITypeInfo **ppTypeInfo)
  297. {
  298. UNREFERENCED_PARAMETER(ppTypeInfo);
  299. if (!pstrName || !ppunkItem)
  300. return E_POINTER;
  301. if ((StrCmpW(L"JSProxy",pstrName) == 0) && (dwReturnMask == SCRIPTINFO_IUNKNOWN))
  302. {
  303. *ppunkItem = (LPUNKNOWN)(IDispatch*)(CJSProxy*)m_punkJSProxy;
  304. (*ppunkItem)->AddRef();
  305. return S_OK;
  306. }
  307. else
  308. return TYPE_E_ELEMENTNOTFOUND;
  309. }
  310. STDMETHODIMP CScriptSite::GetDocVersionString(BSTR *pstrVersionString)
  311. {
  312. UNREFERENCED_PARAMETER(pstrVersionString);
  313. return E_NOTIMPL;
  314. }
  315. // I am not interested it the transitioning of state or the status of where we are in
  316. // the executing of the script.
  317. STDMETHODIMP CScriptSite::OnScriptTerminate(const VARIANT *pvarResult,const EXCEPINFO *pexcepinfo)
  318. {
  319. UNREFERENCED_PARAMETER(pvarResult);
  320. UNREFERENCED_PARAMETER(pexcepinfo);
  321. return S_OK;
  322. }
  323. STDMETHODIMP CScriptSite::OnStateChange(SCRIPTSTATE ssScriptState)
  324. {
  325. UNREFERENCED_PARAMETER(ssScriptState);
  326. return S_OK;
  327. }
  328. STDMETHODIMP CScriptSite::OnScriptError(IActiveScriptError *pase)
  329. {
  330. UNREFERENCED_PARAMETER(pase);
  331. return S_OK;
  332. }
  333. STDMETHODIMP CScriptSite::OnEnterScript()
  334. {
  335. return S_OK;
  336. }
  337. STDMETHODIMP CScriptSite::OnLeaveScript()
  338. {
  339. return S_OK;
  340. }
  341. //
  342. // IServiceProvider
  343. //
  344. // Implemented to help wire up the script engine with our
  345. // IInternetHostSecurityManager interface.
  346. //
  347. STDMETHODIMP CScriptSite::QueryService(
  348. REFGUID guidService,
  349. REFIID riid,
  350. void ** ppvObject)
  351. {
  352. if (guidService == SID_SInternetHostSecurityManager)
  353. {
  354. return QueryInterface(riid, ppvObject);
  355. }
  356. else
  357. {
  358. return E_NOINTERFACE;
  359. }
  360. }
  361. //
  362. // IActiveScriptSiteInterruptPoll
  363. //
  364. STDMETHODIMP CScriptSite::QueryContinue(void)
  365. {
  366. if (m_pAutoProxy->IsSessionAborted())
  367. return E_ABORT;
  368. if (GetTickCount() > (m_dwScriptStartTime + MAX_PAC_SCRIPT_RUN_TIMEOUT))
  369. return E_ABORT;
  370. return NOERROR;
  371. }
  372. //
  373. // IInternetHostSecurityManager
  374. //
  375. // Implemented to prevent the script code from using ActiveX objects.
  376. //
  377. STDMETHODIMP CScriptSite::GetSecurityId(
  378. BYTE * pbSecurityId,
  379. DWORD * pcbSecurityId,
  380. DWORD_PTR dwReserved)
  381. {
  382. UNREFERENCED_PARAMETER(pbSecurityId);
  383. UNREFERENCED_PARAMETER(pcbSecurityId);
  384. UNREFERENCED_PARAMETER(dwReserved);
  385. return E_NOTIMPL;
  386. }
  387. STDMETHODIMP CScriptSite::ProcessUrlAction(
  388. DWORD dwAction,
  389. BYTE * pPolicy,
  390. DWORD cbPolicy,
  391. BYTE * pContext,
  392. DWORD cbContext,
  393. DWORD dwFlags,
  394. DWORD dwReserved)
  395. {
  396. UNREFERENCED_PARAMETER(dwAction);
  397. UNREFERENCED_PARAMETER(pContext);
  398. UNREFERENCED_PARAMETER(cbContext);
  399. UNREFERENCED_PARAMETER(dwFlags);
  400. UNREFERENCED_PARAMETER(dwReserved);
  401. //
  402. // Deny the script any capabilites. In particular, this
  403. // will disallow the script code from instantiating
  404. // ActiveX objects.
  405. //
  406. if (cbPolicy == sizeof(DWORD))
  407. {
  408. *(DWORD *)pPolicy = URLPOLICY_DISALLOW;
  409. }
  410. return S_FALSE; // S_FALSE means the policy != URLPOLICY_ALLOW.
  411. }
  412. STDMETHODIMP CScriptSite::QueryCustomPolicy(
  413. REFGUID guidKey,
  414. BYTE ** ppPolicy,
  415. DWORD * pcbPolicy,
  416. BYTE * pContext,
  417. DWORD cbContext,
  418. DWORD dwReserved)
  419. {
  420. UNREFERENCED_PARAMETER(guidKey);
  421. UNREFERENCED_PARAMETER(ppPolicy);
  422. UNREFERENCED_PARAMETER(pcbPolicy);
  423. UNREFERENCED_PARAMETER(pContext);
  424. UNREFERENCED_PARAMETER(cbContext);
  425. UNREFERENCED_PARAMETER(dwReserved);
  426. return E_NOTIMPL;
  427. }