Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenscript.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2008 Jacek Caban for CodeWeavers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "config.h" 00020 00021 #include <stdarg.h> 00022 00023 #define COBJMACROS 00024 00025 #include "windef.h" 00026 #include "winbase.h" 00027 #include "winuser.h" 00028 #include "ole2.h" 00029 #include "activscp.h" 00030 #include "activdbg.h" 00031 #include "objsafe.h" 00032 00033 #include "wine/debug.h" 00034 00035 #include "mshtml_private.h" 00036 00037 WINE_DEFAULT_DEBUG_CHANNEL(mshtml); 00038 00039 static const WCHAR windowW[] = {'w','i','n','d','o','w',0}; 00040 static const WCHAR emptyW[] = {0}; 00041 00042 static const CLSID CLSID_JScript = 00043 {0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}}; 00044 00045 struct ScriptHost { 00046 const IActiveScriptSiteVtbl *lpIActiveScriptSiteVtbl; 00047 const IActiveScriptSiteInterruptPollVtbl *lpIActiveScriptSiteInterruptPollVtbl; 00048 const IActiveScriptSiteWindowVtbl *lpIActiveScriptSiteWindowVtbl; 00049 const IActiveScriptSiteDebug32Vtbl *lpIActiveScriptSiteDebug32Vtbl; 00050 const IServiceProviderVtbl *lpServiceProviderVtbl; 00051 00052 LONG ref; 00053 00054 IActiveScript *script; 00055 IActiveScriptParse *parse; 00056 IActiveScriptParseProcedure *parse_proc; 00057 00058 SCRIPTSTATE script_state; 00059 00060 HTMLWindow *window; 00061 00062 GUID guid; 00063 struct list entry; 00064 }; 00065 00066 #define ACTSCPSITE(x) ((IActiveScriptSite*) &(x)->lpIActiveScriptSiteVtbl) 00067 #define ACTSCPPOLL(x) (&(x)->lpIActiveScriptSiteInterruptPollVtbl) 00068 #define ACTSCPWIN(x) (&(x)->lpIActiveScriptSiteWindowVtbl) 00069 #define ACTSCPDBG32(x) (&(x)->lpIActiveScriptSiteDebug32Vtbl) 00070 00071 static void set_script_prop(ScriptHost *script_host, DWORD property, VARIANT *val) 00072 { 00073 IActiveScriptProperty *script_prop; 00074 HRESULT hres; 00075 00076 hres = IActiveScript_QueryInterface(script_host->script, &IID_IActiveScriptProperty, 00077 (void**)&script_prop); 00078 if(FAILED(hres)) { 00079 WARN("Could not get IActiveScriptProperty iface: %08x\n", hres); 00080 return; 00081 } 00082 00083 hres = IActiveScriptProperty_SetProperty(script_prop, property, NULL, val); 00084 IActiveScriptProperty_Release(script_prop); 00085 if(FAILED(hres)) 00086 WARN("SetProperty(%x) failed: %08x\n", property, hres); 00087 } 00088 00089 static BOOL init_script_engine(ScriptHost *script_host) 00090 { 00091 IObjectSafety *safety; 00092 SCRIPTSTATE state; 00093 DWORD supported_opts=0, enabled_opts=0; 00094 VARIANT var; 00095 HRESULT hres; 00096 00097 hres = IActiveScript_QueryInterface(script_host->script, &IID_IActiveScriptParse, (void**)&script_host->parse); 00098 if(FAILED(hres)) { 00099 WARN("Could not get IActiveScriptHost: %08x\n", hres); 00100 return FALSE; 00101 } 00102 00103 hres = IActiveScript_QueryInterface(script_host->script, &IID_IObjectSafety, (void**)&safety); 00104 if(FAILED(hres)) { 00105 FIXME("Could not get IObjectSafety: %08x\n", hres); 00106 return FALSE; 00107 } 00108 00109 hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported_opts, &enabled_opts); 00110 if(FAILED(hres)) { 00111 FIXME("GetInterfaceSafetyOptions failed: %08x\n", hres); 00112 }else if(!(supported_opts & INTERFACE_USES_DISPEX)) { 00113 FIXME("INTERFACE_USES_DISPEX is not supported\n"); 00114 }else { 00115 hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, 00116 INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER, 00117 INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER); 00118 if(FAILED(hres)) 00119 FIXME("SetInterfaceSafetyOptions failed: %08x\n", hres); 00120 } 00121 00122 IObjectSafety_Release(safety); 00123 if(FAILED(hres)) 00124 return FALSE; 00125 00126 V_VT(&var) = VT_I4; 00127 V_I4(&var) = 1; 00128 set_script_prop(script_host, SCRIPTPROP_INVOKEVERSIONING, &var); 00129 00130 V_VT(&var) = VT_BOOL; 00131 V_BOOL(&var) = VARIANT_TRUE; 00132 set_script_prop(script_host, SCRIPTPROP_HACK_TRIDENTEVENTSINK, &var); 00133 00134 hres = IActiveScriptParse64_InitNew(script_host->parse); 00135 if(FAILED(hres)) { 00136 WARN("InitNew failed: %08x\n", hres); 00137 return FALSE; 00138 } 00139 00140 hres = IActiveScript_SetScriptSite(script_host->script, ACTSCPSITE(script_host)); 00141 if(FAILED(hres)) { 00142 WARN("SetScriptSite failed: %08x\n", hres); 00143 IActiveScript_Close(script_host->script); 00144 return FALSE; 00145 } 00146 00147 hres = IActiveScript_GetScriptState(script_host->script, &state); 00148 if(FAILED(hres)) 00149 WARN("GetScriptState failed: %08x\n", hres); 00150 else if(state != SCRIPTSTATE_INITIALIZED) 00151 FIXME("state = %x\n", state); 00152 00153 hres = IActiveScript_SetScriptState(script_host->script, SCRIPTSTATE_STARTED); 00154 if(FAILED(hres)) { 00155 WARN("Starting script failed: %08x\n", hres); 00156 return FALSE; 00157 } 00158 00159 hres = IActiveScript_AddNamedItem(script_host->script, windowW, 00160 SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS); 00161 if(SUCCEEDED(hres)) { 00162 V_VT(&var) = VT_BOOL; 00163 V_BOOL(&var) = VARIANT_TRUE; 00164 set_script_prop(script_host, SCRIPTPROP_ABBREVIATE_GLOBALNAME_RESOLUTION, &var); 00165 }else { 00166 WARN("AddNamedItem failed: %08x\n", hres); 00167 } 00168 00169 hres = IActiveScript_QueryInterface(script_host->script, &IID_IActiveScriptParseProcedure2, 00170 (void**)&script_host->parse_proc); 00171 if(FAILED(hres)) { 00172 /* FIXME: QI for IActiveScriptParseProcedure */ 00173 WARN("Could not get IActiveScriptParseProcedure iface: %08x\n", hres); 00174 } 00175 00176 return TRUE; 00177 } 00178 00179 static void release_script_engine(ScriptHost *This) 00180 { 00181 if(!This->script) 00182 return; 00183 00184 switch(This->script_state) { 00185 case SCRIPTSTATE_CONNECTED: 00186 IActiveScript_SetScriptState(This->script, SCRIPTSTATE_DISCONNECTED); 00187 00188 case SCRIPTSTATE_STARTED: 00189 case SCRIPTSTATE_DISCONNECTED: 00190 case SCRIPTSTATE_INITIALIZED: 00191 IActiveScript_Close(This->script); 00192 00193 default: 00194 if(This->parse_proc) { 00195 IUnknown_Release(This->parse_proc); 00196 This->parse_proc = NULL; 00197 } 00198 00199 if(This->parse) { 00200 IUnknown_Release(This->parse); 00201 This->parse = NULL; 00202 } 00203 } 00204 00205 IActiveScript_Release(This->script); 00206 This->script = NULL; 00207 This->script_state = SCRIPTSTATE_UNINITIALIZED; 00208 } 00209 00210 void connect_scripts(HTMLWindow *window) 00211 { 00212 ScriptHost *iter; 00213 00214 LIST_FOR_EACH_ENTRY(iter, &window->script_hosts, ScriptHost, entry) { 00215 if(iter->script_state == SCRIPTSTATE_STARTED) 00216 IActiveScript_SetScriptState(iter->script, SCRIPTSTATE_CONNECTED); 00217 } 00218 } 00219 00220 #define ACTSCPSITE_THIS(iface) DEFINE_THIS(ScriptHost, IActiveScriptSite, iface) 00221 00222 static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv) 00223 { 00224 ScriptHost *This = ACTSCPSITE_THIS(iface); 00225 00226 *ppv = NULL; 00227 00228 if(IsEqualGUID(&IID_IUnknown, riid)) { 00229 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); 00230 *ppv = ACTSCPSITE(This); 00231 }else if(IsEqualGUID(&IID_IActiveScriptSite, riid)) { 00232 TRACE("(%p)->(IID_IActiveScriptSite %p)\n", This, ppv); 00233 *ppv = ACTSCPSITE(This); 00234 }else if(IsEqualGUID(&IID_IActiveScriptSiteInterruptPoll, riid)) { 00235 TRACE("(%p)->(IID_IActiveScriptSiteInterruprtPoll %p)\n", This, ppv); 00236 *ppv = ACTSCPPOLL(This); 00237 }else if(IsEqualGUID(&IID_IActiveScriptSiteWindow, riid)) { 00238 TRACE("(%p)->(IID_IActiveScriptSiteWindow %p)\n", This, ppv); 00239 *ppv = ACTSCPWIN(This); 00240 }else if(IsEqualGUID(&IID_IActiveScriptSiteDebug32, riid)) { 00241 TRACE("(%p)->(IID_IActiveScriptSiteDebug32 %p)\n", This, ppv); 00242 *ppv = ACTSCPDBG32(This); 00243 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { 00244 TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv); 00245 *ppv = SERVPROV(This); 00246 }else if(IsEqualGUID(&IID_ICanHandleException, riid)) { 00247 TRACE("(%p)->(IID_ICanHandleException not supported %p)\n", This, ppv); 00248 return E_NOINTERFACE; 00249 }else { 00250 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); 00251 return E_NOINTERFACE; 00252 } 00253 00254 IUnknown_AddRef((IUnknown*)*ppv); 00255 return S_OK; 00256 } 00257 00258 static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface) 00259 { 00260 ScriptHost *This = ACTSCPSITE_THIS(iface); 00261 LONG ref = InterlockedIncrement(&This->ref); 00262 00263 TRACE("(%p) ref=%d\n", This, ref); 00264 00265 return ref; 00266 } 00267 00268 static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface) 00269 { 00270 ScriptHost *This = ACTSCPSITE_THIS(iface); 00271 LONG ref = InterlockedDecrement(&This->ref); 00272 00273 TRACE("(%p) ref=%d\n", This, ref); 00274 00275 if(!ref) { 00276 release_script_engine(This); 00277 if(This->window) 00278 list_remove(&This->entry); 00279 heap_free(This); 00280 } 00281 00282 return ref; 00283 } 00284 00285 static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *plcid) 00286 { 00287 ScriptHost *This = ACTSCPSITE_THIS(iface); 00288 00289 TRACE("(%p)->(%p)\n", This, plcid); 00290 00291 *plcid = GetUserDefaultLCID(); 00292 return S_OK; 00293 } 00294 00295 static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR pstrName, 00296 DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti) 00297 { 00298 ScriptHost *This = ACTSCPSITE_THIS(iface); 00299 00300 TRACE("(%p)->(%s %x %p %p)\n", This, debugstr_w(pstrName), dwReturnMask, ppiunkItem, ppti); 00301 00302 if(dwReturnMask != SCRIPTINFO_IUNKNOWN) { 00303 FIXME("Unsupported mask %x\n", dwReturnMask); 00304 return E_NOTIMPL; 00305 } 00306 00307 *ppiunkItem = NULL; 00308 00309 if(strcmpW(pstrName, windowW)) 00310 return DISP_E_MEMBERNOTFOUND; 00311 00312 if(!This->window) 00313 return E_FAIL; 00314 00315 /* FIXME: Return proxy object */ 00316 *ppiunkItem = (IUnknown*)HTMLWINDOW2(This->window); 00317 IUnknown_AddRef(*ppiunkItem); 00318 00319 return S_OK; 00320 } 00321 00322 static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *pbstrVersion) 00323 { 00324 ScriptHost *This = ACTSCPSITE_THIS(iface); 00325 FIXME("(%p)->(%p)\n", This, pbstrVersion); 00326 return E_NOTIMPL; 00327 } 00328 00329 static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface, 00330 const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo) 00331 { 00332 ScriptHost *This = ACTSCPSITE_THIS(iface); 00333 FIXME("(%p)->(%p %p)\n", This, pvarResult, pexcepinfo); 00334 return E_NOTIMPL; 00335 } 00336 00337 static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE ssScriptState) 00338 { 00339 ScriptHost *This = ACTSCPSITE_THIS(iface); 00340 00341 TRACE("(%p)->(%x)\n", This, ssScriptState); 00342 00343 This->script_state = ssScriptState; 00344 return S_OK; 00345 } 00346 00347 static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror) 00348 { 00349 ScriptHost *This = ACTSCPSITE_THIS(iface); 00350 FIXME("(%p)->(%p)\n", This, pscripterror); 00351 return E_NOTIMPL; 00352 } 00353 00354 static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface) 00355 { 00356 ScriptHost *This = ACTSCPSITE_THIS(iface); 00357 00358 TRACE("(%p)->()\n", This); 00359 00360 return S_OK; 00361 } 00362 00363 static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface) 00364 { 00365 ScriptHost *This = ACTSCPSITE_THIS(iface); 00366 00367 TRACE("(%p)->()\n", This); 00368 00369 return S_OK; 00370 } 00371 00372 #undef ACTSCPSITE_THIS 00373 00374 static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = { 00375 ActiveScriptSite_QueryInterface, 00376 ActiveScriptSite_AddRef, 00377 ActiveScriptSite_Release, 00378 ActiveScriptSite_GetLCID, 00379 ActiveScriptSite_GetItemInfo, 00380 ActiveScriptSite_GetDocVersionString, 00381 ActiveScriptSite_OnScriptTerminate, 00382 ActiveScriptSite_OnStateChange, 00383 ActiveScriptSite_OnScriptError, 00384 ActiveScriptSite_OnEnterScript, 00385 ActiveScriptSite_OnLeaveScript 00386 }; 00387 00388 #define ACTSCPPOLL_THIS(iface) DEFINE_THIS(ScriptHost, IActiveScriptSiteInterruptPoll, iface) 00389 00390 static HRESULT WINAPI ActiveScriptSiteInterruptPoll_QueryInterface(IActiveScriptSiteInterruptPoll *iface, 00391 REFIID riid, void **ppv) 00392 { 00393 ScriptHost *This = ACTSCPPOLL_THIS(iface); 00394 return IActiveScriptSite_QueryInterface(ACTSCPSITE(This), riid, ppv); 00395 } 00396 00397 static ULONG WINAPI ActiveScriptSiteInterruptPoll_AddRef(IActiveScriptSiteInterruptPoll *iface) 00398 { 00399 ScriptHost *This = ACTSCPPOLL_THIS(iface); 00400 return IActiveScriptSite_AddRef(ACTSCPSITE(This)); 00401 } 00402 00403 static ULONG WINAPI ActiveScriptSiteInterruptPoll_Release(IActiveScriptSiteInterruptPoll *iface) 00404 { 00405 ScriptHost *This = ACTSCPPOLL_THIS(iface); 00406 return IActiveScriptSite_Release(ACTSCPSITE(This)); 00407 } 00408 00409 static HRESULT WINAPI ActiveScriptSiteInterruptPoll_QueryContinue(IActiveScriptSiteInterruptPoll *iface) 00410 { 00411 ScriptHost *This = ACTSCPPOLL_THIS(iface); 00412 00413 TRACE("(%p)\n", This); 00414 00415 return S_OK; 00416 } 00417 00418 #undef ACTSCPPOLL_THIS 00419 00420 static const IActiveScriptSiteInterruptPollVtbl ActiveScriptSiteInterruptPollVtbl = { 00421 ActiveScriptSiteInterruptPoll_QueryInterface, 00422 ActiveScriptSiteInterruptPoll_AddRef, 00423 ActiveScriptSiteInterruptPoll_Release, 00424 ActiveScriptSiteInterruptPoll_QueryContinue 00425 }; 00426 00427 #define ACTSCPWIN_THIS(iface) DEFINE_THIS(ScriptHost, IActiveScriptSiteWindow, iface) 00428 00429 static HRESULT WINAPI ActiveScriptSiteWindow_QueryInterface(IActiveScriptSiteWindow *iface, 00430 REFIID riid, void **ppv) 00431 { 00432 ScriptHost *This = ACTSCPWIN_THIS(iface); 00433 return IActiveScriptSite_QueryInterface(ACTSCPSITE(This), riid, ppv); 00434 } 00435 00436 static ULONG WINAPI ActiveScriptSiteWindow_AddRef(IActiveScriptSiteWindow *iface) 00437 { 00438 ScriptHost *This = ACTSCPWIN_THIS(iface); 00439 return IActiveScriptSite_AddRef(ACTSCPSITE(This)); 00440 } 00441 00442 static ULONG WINAPI ActiveScriptSiteWindow_Release(IActiveScriptSiteWindow *iface) 00443 { 00444 ScriptHost *This = ACTSCPWIN_THIS(iface); 00445 return IActiveScriptSite_Release(ACTSCPSITE(This)); 00446 } 00447 00448 static HRESULT WINAPI ActiveScriptSiteWindow_GetWindow(IActiveScriptSiteWindow *iface, HWND *phwnd) 00449 { 00450 ScriptHost *This = ACTSCPWIN_THIS(iface); 00451 FIXME("(%p)->(%p)\n", This, phwnd); 00452 return E_NOTIMPL; 00453 } 00454 00455 static HRESULT WINAPI ActiveScriptSiteWindow_EnableModeless(IActiveScriptSiteWindow *iface, BOOL fEnable) 00456 { 00457 ScriptHost *This = ACTSCPWIN_THIS(iface); 00458 FIXME("(%p)->(%x)\n", This, fEnable); 00459 return E_NOTIMPL; 00460 } 00461 00462 #undef ACTSCPWIN_THIS 00463 00464 static const IActiveScriptSiteWindowVtbl ActiveScriptSiteWindowVtbl = { 00465 ActiveScriptSiteWindow_QueryInterface, 00466 ActiveScriptSiteWindow_AddRef, 00467 ActiveScriptSiteWindow_Release, 00468 ActiveScriptSiteWindow_GetWindow, 00469 ActiveScriptSiteWindow_EnableModeless 00470 }; 00471 00472 #define ACTSCPDBG32_THIS(iface) DEFINE_THIS(ScriptHost, IActiveScriptSiteDebug32, iface) 00473 00474 static HRESULT WINAPI ActiveScriptSiteDebug32_QueryInterface(IActiveScriptSiteDebug32 *iface, 00475 REFIID riid, void **ppv) 00476 { 00477 ScriptHost *This = ACTSCPDBG32_THIS(iface); 00478 return IActiveScriptSite_QueryInterface(ACTSCPSITE(This), riid, ppv); 00479 } 00480 00481 static ULONG WINAPI ActiveScriptSiteDebug32_AddRef(IActiveScriptSiteDebug32 *iface) 00482 { 00483 ScriptHost *This = ACTSCPDBG32_THIS(iface); 00484 return IActiveScriptSite_AddRef(ACTSCPSITE(This)); 00485 } 00486 00487 static ULONG WINAPI ActiveScriptSiteDebug32_Release(IActiveScriptSiteDebug32 *iface) 00488 { 00489 ScriptHost *This = ACTSCPDBG32_THIS(iface); 00490 return IActiveScriptSite_Release(ACTSCPSITE(This)); 00491 } 00492 00493 static HRESULT WINAPI ActiveScriptSiteDebug32_GetDocumentContextFromPosition(IActiveScriptSiteDebug32 *iface, 00494 DWORD dwSourceContext, ULONG uCharacterOffset, ULONG uNumChars, IDebugDocumentContext **ppsc) 00495 { 00496 ScriptHost *This = ACTSCPDBG32_THIS(iface); 00497 FIXME("(%p)->(%x %u %u %p)\n", This, dwSourceContext, uCharacterOffset, uNumChars, ppsc); 00498 return E_NOTIMPL; 00499 } 00500 00501 static HRESULT WINAPI ActiveScriptSiteDebug32_GetApplication(IActiveScriptSiteDebug32 *iface, IDebugApplication32 **ppda) 00502 { 00503 ScriptHost *This = ACTSCPDBG32_THIS(iface); 00504 FIXME("(%p)->(%p)\n", This, ppda); 00505 return E_NOTIMPL; 00506 } 00507 00508 static HRESULT WINAPI ActiveScriptSiteDebug32_GetRootApplicationNode(IActiveScriptSiteDebug32 *iface, 00509 IDebugApplicationNode **ppdanRoot) 00510 { 00511 ScriptHost *This = ACTSCPDBG32_THIS(iface); 00512 FIXME("(%p)->(%p)\n", This, ppdanRoot); 00513 return E_NOTIMPL; 00514 } 00515 00516 static HRESULT WINAPI ActiveScriptSiteDebug32_OnScriptErrorDebug(IActiveScriptSiteDebug32 *iface, 00517 IActiveScriptErrorDebug *pErrorDebug, BOOL *pfEnterDebugger, BOOL *pfCallOnScriptErrorWhenContinuing) 00518 { 00519 ScriptHost *This = ACTSCPDBG32_THIS(iface); 00520 FIXME("(%p)->(%p %p %p)\n", This, pErrorDebug, pfEnterDebugger, pfCallOnScriptErrorWhenContinuing); 00521 return E_NOTIMPL; 00522 } 00523 00524 #undef ACTSCPDBG32_THIS 00525 00526 static const IActiveScriptSiteDebug32Vtbl ActiveScriptSiteDebug32Vtbl = { 00527 ActiveScriptSiteDebug32_QueryInterface, 00528 ActiveScriptSiteDebug32_AddRef, 00529 ActiveScriptSiteDebug32_Release, 00530 ActiveScriptSiteDebug32_GetDocumentContextFromPosition, 00531 ActiveScriptSiteDebug32_GetApplication, 00532 ActiveScriptSiteDebug32_GetRootApplicationNode, 00533 ActiveScriptSiteDebug32_OnScriptErrorDebug 00534 }; 00535 00536 #define SERVPROV_THIS(iface) DEFINE_THIS(ScriptHost, ServiceProvider, iface) 00537 00538 static HRESULT WINAPI ASServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv) 00539 { 00540 ScriptHost *This = SERVPROV_THIS(iface); 00541 return IActiveScriptSite_QueryInterface(ACTSCPSITE(This), riid, ppv); 00542 } 00543 00544 static ULONG WINAPI ASServiceProvider_AddRef(IServiceProvider *iface) 00545 { 00546 ScriptHost *This = SERVPROV_THIS(iface); 00547 return IActiveScriptSite_AddRef(ACTSCPSITE(This)); 00548 } 00549 00550 static ULONG WINAPI ASServiceProvider_Release(IServiceProvider *iface) 00551 { 00552 ScriptHost *This = SERVPROV_THIS(iface); 00553 return IActiveScriptSite_Release(ACTSCPSITE(This)); 00554 } 00555 00556 static HRESULT WINAPI ASServiceProvider_QueryService(IServiceProvider *iface, REFGUID guidService, 00557 REFIID riid, void **ppv) 00558 { 00559 ScriptHost *This = SERVPROV_THIS(iface); 00560 00561 if(IsEqualGUID(&SID_SInternetHostSecurityManager, guidService)) { 00562 TRACE("(%p)->(SID_SInternetHostSecurityManager)\n", This); 00563 00564 if(!This->window || !This->window->doc) 00565 return E_NOINTERFACE; 00566 00567 return IInternetHostSecurityManager_QueryInterface(HOSTSECMGR(This->window->doc), riid, ppv); 00568 } 00569 00570 FIXME("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv); 00571 return E_NOINTERFACE; 00572 } 00573 00574 #undef SERVPROV_THIS 00575 00576 static const IServiceProviderVtbl ASServiceProviderVtbl = { 00577 ASServiceProvider_QueryInterface, 00578 ASServiceProvider_AddRef, 00579 ASServiceProvider_Release, 00580 ASServiceProvider_QueryService 00581 }; 00582 00583 static ScriptHost *create_script_host(HTMLWindow *window, const GUID *guid) 00584 { 00585 ScriptHost *ret; 00586 HRESULT hres; 00587 00588 ret = heap_alloc_zero(sizeof(*ret)); 00589 ret->lpIActiveScriptSiteVtbl = &ActiveScriptSiteVtbl; 00590 ret->lpIActiveScriptSiteInterruptPollVtbl = &ActiveScriptSiteInterruptPollVtbl; 00591 ret->lpIActiveScriptSiteWindowVtbl = &ActiveScriptSiteWindowVtbl; 00592 ret->lpIActiveScriptSiteDebug32Vtbl = &ActiveScriptSiteDebug32Vtbl; 00593 ret->lpServiceProviderVtbl = &ASServiceProviderVtbl; 00594 ret->ref = 1; 00595 ret->window = window; 00596 ret->script_state = SCRIPTSTATE_UNINITIALIZED; 00597 00598 ret->guid = *guid; 00599 list_add_tail(&window->script_hosts, &ret->entry); 00600 00601 hres = CoCreateInstance(&ret->guid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, 00602 &IID_IActiveScript, (void**)&ret->script); 00603 if(FAILED(hres)) 00604 WARN("Could not load script engine: %08x\n", hres); 00605 else if(!init_script_engine(ret)) 00606 release_script_engine(ret); 00607 00608 return ret; 00609 } 00610 00611 static void parse_text(ScriptHost *script_host, LPCWSTR text) 00612 { 00613 EXCEPINFO excepinfo; 00614 VARIANT var; 00615 HRESULT hres; 00616 00617 static const WCHAR script_endW[] = {'<','/','S','C','R','I','P','T','>',0}; 00618 00619 TRACE("%s\n", debugstr_w(text)); 00620 00621 VariantInit(&var); 00622 memset(&excepinfo, 0, sizeof(excepinfo)); 00623 TRACE(">>>\n"); 00624 hres = IActiveScriptParse64_ParseScriptText(script_host->parse, text, windowW, NULL, script_endW, 00625 0, 0, SCRIPTTEXT_ISVISIBLE|SCRIPTTEXT_HOSTMANAGESSOURCE, 00626 &var, &excepinfo); 00627 if(SUCCEEDED(hres)) 00628 TRACE("<<<\n"); 00629 else 00630 WARN("<<< %08x\n", hres); 00631 00632 } 00633 00634 static void parse_extern_script(ScriptHost *script_host, LPCWSTR src) 00635 { 00636 IMoniker *mon; 00637 char *buf; 00638 WCHAR *text; 00639 DWORD len, size=0; 00640 HRESULT hres; 00641 00642 static const WCHAR wine_schemaW[] = {'w','i','n','e',':'}; 00643 00644 if(strlenW(src) > sizeof(wine_schemaW)/sizeof(WCHAR) && !memcmp(src, wine_schemaW, sizeof(wine_schemaW))) 00645 src += sizeof(wine_schemaW)/sizeof(WCHAR); 00646 00647 hres = CreateURLMoniker(NULL, src, &mon); 00648 if(FAILED(hres)) 00649 return; 00650 00651 hres = bind_mon_to_buffer(script_host->window->doc, mon, (void**)&buf, &size); 00652 IMoniker_Release(mon); 00653 if(FAILED(hres)) 00654 return; 00655 00656 len = MultiByteToWideChar(CP_ACP, 0, buf, size, NULL, 0); 00657 text = heap_alloc((len+1)*sizeof(WCHAR)); 00658 MultiByteToWideChar(CP_ACP, 0, buf, size, text, len); 00659 heap_free(buf); 00660 text[len] = 0; 00661 00662 parse_text(script_host, text); 00663 00664 heap_free(text); 00665 } 00666 00667 static void parse_inline_script(ScriptHost *script_host, nsIDOMHTMLScriptElement *nsscript) 00668 { 00669 const PRUnichar *text; 00670 nsAString text_str; 00671 nsresult nsres; 00672 00673 nsAString_Init(&text_str, NULL); 00674 00675 nsres = nsIDOMHTMLScriptElement_GetText(nsscript, &text_str); 00676 00677 if(NS_SUCCEEDED(nsres)) { 00678 nsAString_GetData(&text_str, &text); 00679 parse_text(script_host, text); 00680 }else { 00681 ERR("GetText failed: %08x\n", nsres); 00682 } 00683 00684 nsAString_Finish(&text_str); 00685 } 00686 00687 static void parse_script_elem(ScriptHost *script_host, nsIDOMHTMLScriptElement *nsscript) 00688 { 00689 const PRUnichar *src; 00690 nsAString src_str; 00691 nsresult nsres; 00692 00693 nsAString_Init(&src_str, NULL); 00694 00695 nsres = nsIDOMHTMLScriptElement_GetSrc(nsscript, &src_str); 00696 nsAString_GetData(&src_str, &src); 00697 00698 if(NS_FAILED(nsres)) 00699 ERR("GetSrc failed: %08x\n", nsres); 00700 else if(*src) 00701 parse_extern_script(script_host, src); 00702 else 00703 parse_inline_script(script_host, nsscript); 00704 00705 nsAString_Finish(&src_str); 00706 } 00707 00708 static BOOL get_guid_from_type(LPCWSTR type, GUID *guid) 00709 { 00710 const WCHAR text_javascriptW[] = 00711 {'t','e','x','t','/','j','a','v','a','s','c','r','i','p','t',0}; 00712 00713 /* FIXME: Handle more types */ 00714 if(!strcmpiW(type, text_javascriptW)) { 00715 *guid = CLSID_JScript; 00716 }else { 00717 FIXME("Unknown type %s\n", debugstr_w(type)); 00718 return FALSE; 00719 } 00720 00721 return TRUE; 00722 } 00723 00724 static BOOL get_guid_from_language(LPCWSTR type, GUID *guid) 00725 { 00726 HRESULT hres; 00727 00728 hres = CLSIDFromProgID(type, guid); 00729 if(FAILED(hres)) 00730 return FALSE; 00731 00732 /* FIXME: Check CATID_ActiveScriptParse */ 00733 00734 return TRUE; 00735 } 00736 00737 static BOOL get_script_guid(nsIDOMHTMLScriptElement *nsscript, GUID *guid) 00738 { 00739 nsAString attr_str, val_str; 00740 BOOL ret = FALSE; 00741 nsresult nsres; 00742 00743 static const PRUnichar languageW[] = {'l','a','n','g','u','a','g','e',0}; 00744 00745 nsAString_Init(&val_str, NULL); 00746 00747 nsres = nsIDOMHTMLScriptElement_GetType(nsscript, &val_str); 00748 if(NS_SUCCEEDED(nsres)) { 00749 const PRUnichar *type; 00750 00751 nsAString_GetData(&val_str, &type); 00752 if(*type) { 00753 ret = get_guid_from_type(type, guid); 00754 nsAString_Finish(&val_str); 00755 return ret; 00756 } 00757 }else { 00758 ERR("GetType failed: %08x\n", nsres); 00759 } 00760 00761 nsAString_InitDepend(&attr_str, languageW); 00762 nsres = nsIDOMHTMLScriptElement_GetAttribute(nsscript, &attr_str, &val_str); 00763 nsAString_Finish(&attr_str); 00764 if(NS_SUCCEEDED(nsres)) { 00765 const PRUnichar *language; 00766 00767 nsAString_GetData(&val_str, &language); 00768 00769 if(*language) { 00770 ret = get_guid_from_language(language, guid); 00771 }else { 00772 *guid = CLSID_JScript; 00773 ret = TRUE; 00774 } 00775 }else { 00776 ERR("GetAttribute(language) failed: %08x\n", nsres); 00777 } 00778 00779 nsAString_Finish(&val_str); 00780 00781 return ret; 00782 } 00783 00784 static ScriptHost *get_script_host(HTMLWindow *window, const GUID *guid) 00785 { 00786 ScriptHost *iter; 00787 00788 if(IsEqualGUID(&CLSID_JScript, guid) && window->scriptmode != SCRIPTMODE_ACTIVESCRIPT) { 00789 TRACE("Ignoring JScript\n"); 00790 return NULL; 00791 } 00792 00793 LIST_FOR_EACH_ENTRY(iter, &window->script_hosts, ScriptHost, entry) { 00794 if(IsEqualGUID(guid, &iter->guid)) 00795 return iter; 00796 } 00797 00798 return create_script_host(window, guid); 00799 } 00800 00801 void doc_insert_script(HTMLWindow *window, nsIDOMHTMLScriptElement *nsscript) 00802 { 00803 ScriptHost *script_host; 00804 GUID guid; 00805 00806 if(!get_script_guid(nsscript, &guid)) { 00807 WARN("Could not find script GUID\n"); 00808 return; 00809 } 00810 00811 script_host = get_script_host(window, &guid); 00812 if(!script_host) 00813 return; 00814 00815 if(script_host->parse) 00816 parse_script_elem(script_host, nsscript); 00817 } 00818 00819 IDispatch *script_parse_event(HTMLWindow *window, LPCWSTR text) 00820 { 00821 ScriptHost *script_host; 00822 GUID guid = CLSID_JScript; 00823 const WCHAR *ptr; 00824 IDispatch *disp; 00825 HRESULT hres; 00826 00827 static const WCHAR delimiterW[] = {'\"',0}; 00828 00829 for(ptr = text; isalnumW(*ptr); ptr++); 00830 if(*ptr == ':') { 00831 LPWSTR language; 00832 BOOL b; 00833 00834 language = heap_alloc((ptr-text+1)*sizeof(WCHAR)); 00835 memcpy(language, text, (ptr-text)*sizeof(WCHAR)); 00836 language[ptr-text] = 0; 00837 00838 b = get_guid_from_language(language, &guid); 00839 00840 heap_free(language); 00841 00842 if(!b) { 00843 WARN("Could not find language\n"); 00844 return NULL; 00845 } 00846 00847 ptr++; 00848 }else { 00849 ptr = text; 00850 } 00851 00852 script_host = get_script_host(window, &guid); 00853 if(!script_host || !script_host->parse_proc) 00854 return NULL; 00855 00856 hres = IActiveScriptParseProcedure64_ParseProcedureText(script_host->parse_proc, ptr, NULL, emptyW, 00857 NULL, NULL, delimiterW, 0 /* FIXME */, 0, 00858 SCRIPTPROC_HOSTMANAGESSOURCE|SCRIPTPROC_IMPLICIT_THIS|SCRIPTPROC_IMPLICIT_PARENTS, &disp); 00859 if(FAILED(hres)) { 00860 WARN("ParseProcedureText failed: %08x\n", hres); 00861 return NULL; 00862 } 00863 00864 TRACE("ret %p\n", disp); 00865 return disp; 00866 } 00867 00868 IDispatch *get_script_disp(ScriptHost *script_host) 00869 { 00870 IDispatch *disp; 00871 HRESULT hres; 00872 00873 if(!script_host->script) 00874 return NULL; 00875 00876 hres = IActiveScript_GetScriptDispatch(script_host->script, windowW, &disp); 00877 if(FAILED(hres)) 00878 return NULL; 00879 00880 return disp; 00881 } 00882 00883 BOOL find_global_prop(HTMLWindow *window, BSTR name, DWORD flags, ScriptHost **ret_host, DISPID *ret_id) 00884 { 00885 IDispatchEx *dispex; 00886 IDispatch *disp; 00887 ScriptHost *iter; 00888 HRESULT hres; 00889 00890 LIST_FOR_EACH_ENTRY(iter, &window->script_hosts, ScriptHost, entry) { 00891 disp = get_script_disp(iter); 00892 if(!disp) 00893 continue; 00894 00895 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); 00896 if(SUCCEEDED(hres)) { 00897 hres = IDispatchEx_GetDispID(dispex, name, flags & (~fdexNameEnsure), ret_id); 00898 IDispatchEx_Release(dispex); 00899 }else { 00900 FIXME("No IDispatchEx\n"); 00901 hres = E_NOTIMPL; 00902 } 00903 00904 IDispatch_Release(disp); 00905 if(SUCCEEDED(hres)) { 00906 *ret_host = iter; 00907 return TRUE; 00908 } 00909 } 00910 00911 return FALSE; 00912 } 00913 00914 static BOOL is_jscript_available(void) 00915 { 00916 static BOOL available, checked; 00917 00918 if(!checked) { 00919 IUnknown *unk; 00920 HRESULT hres = CoGetClassObject(&CLSID_JScript, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); 00921 00922 if(SUCCEEDED(hres)) { 00923 available = TRUE; 00924 IUnknown_Release(unk); 00925 }else { 00926 available = FALSE; 00927 } 00928 checked = TRUE; 00929 } 00930 00931 return available; 00932 } 00933 00934 void set_script_mode(HTMLWindow *window, SCRIPTMODE mode) 00935 { 00936 nsIWebBrowserSetup *setup; 00937 nsresult nsres; 00938 00939 if(mode == SCRIPTMODE_ACTIVESCRIPT && !is_jscript_available()) { 00940 TRACE("jscript.dll not available\n"); 00941 window->scriptmode = SCRIPTMODE_GECKO; 00942 return; 00943 } 00944 00945 window->scriptmode = mode; 00946 00947 if(!window->doc_obj->nscontainer || !window->doc_obj->nscontainer->webbrowser) 00948 return; 00949 00950 nsres = nsIWebBrowser_QueryInterface(window->doc_obj->nscontainer->webbrowser, 00951 &IID_nsIWebBrowserSetup, (void**)&setup); 00952 if(NS_SUCCEEDED(nsres)) { 00953 nsres = nsIWebBrowserSetup_SetProperty(setup, SETUP_ALLOW_JAVASCRIPT, 00954 window->scriptmode == SCRIPTMODE_GECKO); 00955 nsIWebBrowserSetup_Release(setup); 00956 } 00957 00958 if(NS_FAILED(nsres)) 00959 ERR("JavaScript setup failed: %08x\n", nsres); 00960 } 00961 00962 void release_script_hosts(HTMLWindow *window) 00963 { 00964 ScriptHost *iter; 00965 00966 while(!list_empty(&window->script_hosts)) { 00967 iter = LIST_ENTRY(list_head(&window->script_hosts), ScriptHost, entry); 00968 00969 release_script_engine(iter); 00970 list_remove(&iter->entry); 00971 iter->window = NULL; 00972 IActiveScript_Release(ACTSCPSITE(iter)); 00973 } 00974 } Generated on Sun May 27 2012 04:25:07 for ReactOS by
1.7.6.1
|