<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">Hi Nikolay,<br>
<br>
On 14.07.2016 16:35, Nikolay Sivov wrote:<br>
</div>
<blockquote
cite="mid:1468506927-26296-1-git-send-email-nsivov@codeweavers.com"
type="cite">
<div class="moz-text-plain" wrap="true" graphical-quote="true"
style="font-family: -moz-fixed; font-size: 12px;"
lang="x-unicode">
<pre wrap="">
+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);</pre>
</div>
</blockquote>
<br>
This failure is important, please handle it well.<br>
<br>
<blockquote
cite="mid:1468506927-26296-1-git-send-email-nsivov@codeweavers.com"
type="cite">
<div class="moz-text-plain" wrap="true" graphical-quote="true"
style="font-family: -moz-fixed; font-size: 12px;"
lang="x-unicode">
<pre wrap="">
+ 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;
+ }</pre>
</div>
</blockquote>
<br>
This and...<br>
<br>
<blockquote
cite="mid:1468506927-26296-1-git-send-email-nsivov@codeweavers.com"
type="cite">
<div class="moz-text-plain" wrap="true" graphical-quote="true"
style="font-family: -moz-fixed; font-size: 12px;"
lang="x-unicode">
<pre wrap="">
+ hr = IActiveScriptParse_InitNew(host->parse);
+ if (FAILED(hr)) {
+ WARN("InitNew failed, %#x\n", hr);
+ goto failed;
+ }</pre>
</div>
</blockquote>
<br>
...this failure will cause ref leak. You have already set script
site, so engine holds a reference to ScriptHost, but you only
release one reference on failure. Using release_script_engine on
failure should fix that.<br>
<br>
<blockquote
cite="mid:1468506927-26296-1-git-send-email-nsivov@codeweavers.com"
type="cite">
<div class="moz-text-plain" wrap="true" graphical-quote="true"
style="font-family: -moz-fixed; font-size: 12px;"
lang="x-unicode">
<pre wrap="">
+
+ *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));</pre>
</div>
</blockquote>
<br>
How about SysAllocString instead?<br>
<br>
<blockquote
cite="mid:1468506927-26296-1-git-send-email-nsivov@codeweavers.com"
type="cite">
<div class="moz-text-plain" wrap="true" graphical-quote="true"
style="font-family: -moz-fixed; font-size: 12px;"
lang="x-unicode">
<pre wrap="">
+ 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;
+ }</pre>
</div>
</blockquote>
<br>
This will leave zombie script host and engine. You should probably
use release_script_engine here as well.<br>
<br>
<blockquote
cite="mid:1468506927-26296-1-git-send-email-nsivov@codeweavers.com"
type="cite">
<div class="moz-text-plain" wrap="true" graphical-quote="true"
style="font-family: -moz-fixed; font-size: 12px;"
lang="x-unicode">
<pre wrap="">
+
+ 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);
</pre>
</div>
</blockquote>
<br>
Thanks,<br>
Jacek<br>
</body>
</html>