+static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret) +{ + IObjectSafety *objsafety; + ScriptHost *host; + HRESULT hr; + + *ret = NULL; + + host = heap_alloc(sizeof(*host)); + if (!host) + return E_OUTOFMEMORY; + + host->IActiveScriptSite_iface.lpVtbl = &ActiveScriptSiteVtbl; + host->ref = 1; + host->script = NULL; + host->parse = NULL; + host->clsid = *clsid; + + hr = CoCreateInstance(&host->clsid, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IActiveScript, (void**)&host->script); + if (FAILED(hr)) { + WARN("Failed to create an instance for %s, %#x\n", debugstr_guid(clsid), hr); + goto failed; + } + + hr = IActiveScript_QueryInterface(host->script, &IID_IObjectSafety, (void**)&objsafety); + if (FAILED(hr)) { + FIXME("Could not get IObjectSafety, %#x\n", hr); + goto failed; + } + + hr = IObjectSafety_SetInterfaceSafetyOptions(objsafety, &IID_IActiveScriptParse, INTERFACESAFE_FOR_UNTRUSTED_DATA, 0); + if (FAILED(hr)) + FIXME("SetInterfaceSafetyOptions failed, %#x\n", hr);
+ IObjectSafety_Release(objsafety); + + hr = IActiveScript_SetScriptSite(host->script, &host->IActiveScriptSite_iface); + if (FAILED(hr)) { + WARN("SetScriptSite failed, %#x\n", hr); + goto failed; + } + + hr = IActiveScript_QueryInterface(host->script, &IID_IActiveScriptParse, (void**)&host->parse); + if (FAILED(hr)) { + WARN("Failed to get IActiveScriptParse, %#x\n", hr); + goto failed; + }
+ hr = IActiveScriptParse_InitNew(host->parse); + if (FAILED(hr)) { + WARN("InitNew failed, %#x\n", hr); + goto failed; + }
+ + *ret = host; + return S_OK; + +failed: + IActiveScriptSite_Release(&host->IActiveScriptSite_iface); + return hr; +} + static HRESULT WINAPI ScriptControl_QueryInterface(IScriptControl *iface, REFIID riid, void **ppv) { ScriptControl *This = impl_from_IScriptControl(iface); @@ -257,6 +498,10 @@ static ULONG WINAPI ScriptControl_Release(IScriptControl *iface) if(!ref) { if (This->site) IOleClientSite_Release(This->site); + if (This->host) { + release_script_engine(This->host); + IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface); + } heap_free(This); } @@ -321,15 +566,47 @@ static HRESULT WINAPI ScriptControl_Invoke(IScriptControl *iface, DISPID dispIdM static HRESULT WINAPI ScriptControl_get_Language(IScriptControl *iface, BSTR *p) { ScriptControl *This = impl_from_IScriptControl(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + LPOLESTR progidW; + HRESULT hr; + + TRACE("(%p)->(%p)\n", This, p); + + if (!p) + return E_POINTER; + + *p = NULL; + + if (!This->host) + return S_OK; + + hr = ProgIDFromCLSID(&This->host->clsid, &progidW); + if (FAILED(hr)) + return hr; + + *p = SysAllocStringLen(progidW, lstrlenW(progidW));
+ CoTaskMemFree(progidW); + return *p ? S_OK : E_OUTOFMEMORY; } static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR language) { ScriptControl *This = impl_from_IScriptControl(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(language)); - return E_NOTIMPL; + CLSID clsid; + + TRACE("(%p)->(%s)\n", This, debugstr_w(language)); + + if (language && FAILED(CLSIDFromProgID(language, &clsid))) + return CTL_E_INVALIDPROPERTYVALUE; + + if (This->host) { + IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface); + This->host = NULL; + }
+ + if (!language) + return S_OK; + + return init_script_host(&clsid, &This->host); } static HRESULT WINAPI ScriptControl_get_State(IScriptControl *iface, ScriptControlStates *p) @@ -1379,6 +1656,7 @@ static HRESULT WINAPI ScriptControl_CreateInstance(IClassFactory *iface, IUnknow script_control->ref = 1; script_control->site = NULL; script_control->cp_list = NULL; + script_control->host = NULL; ConnectionPoint_Init(&script_control->cp_scsource, script_control, &DIID_DScriptControlSource); ConnectionPoint_Init(&script_control->cp_propnotif, script_control, &IID_IPropertyNotifySink);