ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

script.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.