diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c
index aa7cb08d90c..3388ca193b8 100644
--- a/dlls/mshtml/script.c
+++ b/dlls/mshtml/script.c
@@ -27,6 +27,7 @@
#include "winuser.h"
#include "ole2.h"
#include "activscp.h"
+#include "objsafe.h"
#include "wine/debug.h"
@@ -34,6 +35,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+static const WCHAR windowW[] = {'w','i','n','d','o','w',0};
+
static const CLSID CLSID_JScript =
{0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
@@ -43,6 +46,7 @@ typedef struct {
LONG ref;
IActiveScript *script;
+ IActiveScriptParse *parse;
SCRIPTSTATE script_state;
@@ -54,6 +58,119 @@ typedef struct {
#define ACTSCPSITE(x) ((IActiveScriptSite*) &(x)->lpActiveScriptSiteVtbl)
+static BOOL init_script_engine(ScriptHost *script_host)
+{
+ IActiveScriptProperty *property;
+ IObjectSafety *safety;
+ SCRIPTSTATE state;
+ DWORD supported_opts=0, enabled_opts=0;
+ HRESULT hres;
+
+ hres = IActiveScript_QueryInterface(script_host->script, &IID_IActiveScriptParse, (void**)&script_host->parse);
+ if(FAILED(hres)) {
+ WARN("Could not get IActiveScriptHost: %08x\n", hres);
+ return FALSE;
+ }
+
+ hres = IActiveScript_QueryInterface(script_host->script, &IID_IObjectSafety, (void**)&safety);
+ if(FAILED(hres)) {
+ FIXME("Could not get IObjectSafety: %08x\n", hres);
+ return FALSE;
+ }
+
+ hres = IObjectSafety_GetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse, &supported_opts, &enabled_opts);
+ if(FAILED(hres)) {
+ FIXME("GetInterfaceSafetyOptions failed: %08x\n", hres);
+ }else if(!(supported_opts & INTERFACE_USES_DISPEX)) {
+ FIXME("INTERFACE_USES_DISPEX is not supported\n");
+ }else {
+ hres = IObjectSafety_SetInterfaceSafetyOptions(safety, &IID_IActiveScriptParse,
+ INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER,
+ INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER);
+ if(FAILED(hres))
+ FIXME("SetInterfaceSafetyOptions failed: %08x\n", hres);
+ }
+
+ IObjectSafety_Release(safety);
+ if(FAILED(hres))
+ return FALSE;
+
+ hres = IActiveScript_QueryInterface(script_host->script, &IID_IActiveScriptProperty, (void**)&property);
+ if(SUCCEEDED(hres)) {
+ VARIANT var;
+
+ V_VT(&var) = VT_BOOL;
+ V_BOOL(&var) = VARIANT_TRUE;
+ hres = IActiveScriptProperty_SetProperty(property, SCRIPTPROP_HACK_TRIDENTEVENTSINK, NULL, &var);
+ if(FAILED(hres))
+ WARN("SetProperty failed: %08x\n", hres);
+
+ IActiveScriptProperty_Release(property);
+ }else {
+ WARN("Could not get IActiveScriptProperty: %08x\n", hres);
+ }
+
+ hres = IActiveScriptParse_InitNew(script_host->parse);
+ if(FAILED(hres)) {
+ WARN("InitNew failed: %08x\n", hres);
+ return FALSE;
+ }
+
+ hres = IActiveScript_SetScriptSite(script_host->script, ACTSCPSITE(script_host));
+ if(FAILED(hres)) {
+ WARN("SetScriptSite failed: %08x\n", hres);
+ IActiveScript_Close(script_host->script);
+ return FALSE;
+ }
+
+ hres = IActiveScript_GetScriptState(script_host->script, &state);
+ if(FAILED(hres))
+ WARN("GetScriptState failed: %08x\n", hres);
+ else if(state != SCRIPTSTATE_INITIALIZED)
+ FIXME("state = %x\n", state);
+
+ hres = IActiveScript_SetScriptState(script_host->script, SCRIPTSTATE_STARTED);
+ if(FAILED(hres)) {
+ WARN("Starting script failed: %08x\n", hres);
+ return FALSE;
+ }
+
+ hres = IActiveScript_AddNamedItem(script_host->script, windowW,
+ SCRIPTITEM_ISVISIBLE|SCRIPTITEM_ISSOURCE|SCRIPTITEM_GLOBALMEMBERS);
+ if(FAILED(hres))
+ WARN("AddNamedItem failed: %08x\n", hres);
+
+ /* FIXME: QI for IActiveScriptParseProcedure2 and IActiveScriptParseProcedure */
+
+ return TRUE;
+}
+
+static void release_script_engine(ScriptHost *This)
+{
+ if(!This->script)
+ return;
+
+ switch(This->script_state) {
+ case SCRIPTSTATE_CONNECTED:
+ IActiveScript_SetScriptState(This->script, SCRIPTSTATE_DISCONNECTED);
+
+ case SCRIPTSTATE_STARTED:
+ case SCRIPTSTATE_DISCONNECTED:
+ case SCRIPTSTATE_INITIALIZED:
+ IActiveScript_Close(This->script);
+
+ default:
+ if(This->parse) {
+ IActiveScriptParse_Release(This->parse);
+ This->parse = NULL;
+ }
+ }
+
+ IActiveScript_Release(This->script);
+ This->script = NULL;
+ This->script_state = SCRIPTSTATE_UNINITIALIZED;
+}
+
#define ACTSCPSITE_THIS(iface) DEFINE_THIS(ScriptHost, ActiveScriptSite, iface)
static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
@@ -95,6 +212,7 @@ static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
+ release_script_engine(This);
if(This->doc)
list_remove(&This->entry);
heap_free(This);
@@ -195,8 +313,10 @@ static ScriptHost *create_script_host(HTMLDocument *doc, GUID *guid)
hres = CoCreateInstance(&ret->guid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
&IID_IActiveScript, (void**)&ret->script);
- if(FAILED(hres))
+ if(FAILED(hres))
WARN("Could not load script engine: %08x\n", hres);
+ else if(!init_script_engine(ret))
+ release_script_engine(ret);
return ret;
}
@@ -313,6 +433,7 @@ void release_script_hosts(HTMLDocument *doc)
while(!list_empty(&doc->script_hosts)) {
iter = LIST_ENTRY(list_head(&doc->script_hosts), ScriptHost, entry);
+ release_script_engine(iter);
list_remove(&iter->entry);
iter->doc = NULL;
IActiveScript_Release(ACTSCPSITE(iter));