Commit fcf6d67b authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

msscript.ocx: Keep script host running as long as any script module is alive.

Based on patch by Gabriel Ivăncescu. Signed-off-by: 's avatarJacek Caban <jacek@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 5a6ac3aa
...@@ -51,6 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msscript); ...@@ -51,6 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msscript);
struct ScriptControl; struct ScriptControl;
typedef struct ConnectionPoint ConnectionPoint; typedef struct ConnectionPoint ConnectionPoint;
typedef struct ScriptHost ScriptHost;
struct ConnectionPoint { struct ConnectionPoint {
IConnectionPoint IConnectionPoint_iface; IConnectionPoint IConnectionPoint_iface;
...@@ -68,9 +69,11 @@ struct named_item { ...@@ -68,9 +69,11 @@ struct named_item {
typedef struct { typedef struct {
IScriptModule IScriptModule_iface; IScriptModule IScriptModule_iface;
LONG ref; LONG ref;
ScriptHost *host;
} ScriptModule; } ScriptModule;
typedef struct ScriptHost { struct ScriptHost {
IActiveScriptSite IActiveScriptSite_iface; IActiveScriptSite IActiveScriptSite_iface;
IActiveScriptSiteWindow IActiveScriptSiteWindow_iface; IActiveScriptSiteWindow IActiveScriptSiteWindow_iface;
IServiceProvider IServiceProvider_iface; IServiceProvider IServiceProvider_iface;
...@@ -83,9 +86,8 @@ typedef struct ScriptHost { ...@@ -83,9 +86,8 @@ typedef struct ScriptHost {
CLSID clsid; CLSID clsid;
unsigned int module_count; unsigned int module_count;
struct list named_items; struct list named_items;
} ScriptHost; };
struct ScriptControl { struct ScriptControl {
IScriptControl IScriptControl_iface; IScriptControl IScriptControl_iface;
...@@ -355,25 +357,6 @@ static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface) ...@@ -355,25 +357,6 @@ static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
return ref; return ref;
} }
static void release_script_engine(ScriptHost *host)
{
if (host->script) {
IActiveScript_Close(host->script);
IActiveScript_Release(host->script);
}
if (host->parse)
IActiveScriptParse_Release(host->parse);
if (host->script_dispatch)
IDispatch_Release(host->script_dispatch);
host->script_dispatch = NULL;
host->parse = NULL;
host->script = NULL;
IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
}
static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface) static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
{ {
ScriptHost *This = impl_from_IActiveScriptSite(iface); ScriptHost *This = impl_from_IActiveScriptSite(iface);
...@@ -572,6 +555,26 @@ static const IServiceProviderVtbl ServiceProviderVtbl = { ...@@ -572,6 +555,26 @@ static const IServiceProviderVtbl ServiceProviderVtbl = {
ServiceProvider_QueryService ServiceProvider_QueryService
}; };
static void detach_script_host(ScriptHost *host)
{
if (--host->module_count)
return;
if (host->script) {
IActiveScript_Close(host->script);
IActiveScript_Release(host->script);
}
if (host->parse)
IActiveScriptParse_Release(host->parse);
if (host->script_dispatch)
IDispatch_Release(host->script_dispatch);
host->script_dispatch = NULL;
host->parse = NULL;
host->script = NULL;
}
static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv) static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv)
{ {
ScriptModule *This = impl_from_IScriptModule(iface); ScriptModule *This = impl_from_IScriptModule(iface);
...@@ -610,7 +613,11 @@ static ULONG WINAPI ScriptModule_Release(IScriptModule *iface) ...@@ -610,7 +613,11 @@ static ULONG WINAPI ScriptModule_Release(IScriptModule *iface)
TRACE("(%p) ref=%d\n", This, ref); TRACE("(%p) ref=%d\n", This, ref);
if (!ref) if (!ref)
{
detach_script_host(This->host);
IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
heap_free(This); heap_free(This);
}
return ref; return ref;
} }
...@@ -756,7 +763,7 @@ static const IScriptModuleVtbl ScriptModuleVtbl = { ...@@ -756,7 +763,7 @@ static const IScriptModuleVtbl ScriptModuleVtbl = {
ScriptModule_Run ScriptModule_Run
}; };
static ScriptModule *create_module(void) static ScriptModule *create_module(ScriptHost *host)
{ {
ScriptModule *module; ScriptModule *module;
...@@ -764,6 +771,8 @@ static ScriptModule *create_module(void) ...@@ -764,6 +771,8 @@ static ScriptModule *create_module(void)
module->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl; module->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl;
module->ref = 1; module->ref = 1;
module->host = host;
IActiveScriptSite_AddRef(&host->IActiveScriptSite_iface);
return module; return module;
} }
...@@ -992,7 +1001,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret) ...@@ -992,7 +1001,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret)
return S_OK; return S_OK;
failed: failed:
release_script_engine(host); detach_script_host(host);
return hr; return hr;
} }
...@@ -1072,7 +1081,7 @@ static ULONG WINAPI ScriptControl_Release(IScriptControl *iface) ...@@ -1072,7 +1081,7 @@ static ULONG WINAPI ScriptControl_Release(IScriptControl *iface)
if (This->host) if (This->host)
{ {
release_modules(This); release_modules(This);
release_script_engine(This->host); IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
} }
heap_free(This); heap_free(This);
} }
...@@ -1164,6 +1173,7 @@ static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR lan ...@@ -1164,6 +1173,7 @@ static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR lan
{ {
ScriptControl *This = impl_from_IScriptControl(iface); ScriptControl *This = impl_from_IScriptControl(iface);
CLSID clsid; CLSID clsid;
HRESULT hres;
TRACE("(%p)->(%s)\n", This, debugstr_w(language)); TRACE("(%p)->(%s)\n", This, debugstr_w(language));
...@@ -1171,25 +1181,32 @@ static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR lan ...@@ -1171,25 +1181,32 @@ static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR lan
return CTL_E_INVALIDPROPERTYVALUE; return CTL_E_INVALIDPROPERTYVALUE;
if (This->host) { if (This->host) {
release_script_engine(This->host); release_modules(This);
This->host = NULL; This->host = NULL;
} }
if (!language)
return S_OK;
hres = init_script_host(&clsid, &This->host);
if (FAILED(hres))
return hres;
/* Alloc global module */ /* Alloc global module */
This->modules = heap_alloc_zero(sizeof(*This->modules)); This->modules = heap_alloc_zero(sizeof(*This->modules));
if (!This->modules) return E_OUTOFMEMORY; if (This->modules) {
This->modules[0] = create_module(This->host);
This->modules[0] = create_module();
if (!This->modules[0]) { if (!This->modules[0]) {
heap_free(This->modules); heap_free(This->modules);
This->modules = NULL; This->modules = NULL;
return E_OUTOFMEMORY; hres = E_OUTOFMEMORY;
} }
}
if (!language) if (FAILED(hres)) {
return S_OK; This->host = NULL;
detach_script_host(This->host);
return init_script_host(&clsid, &This->host); }
return hres;
} }
static HRESULT WINAPI ScriptControl_get_State(IScriptControl *iface, ScriptControlStates *p) static HRESULT WINAPI ScriptControl_get_State(IScriptControl *iface, ScriptControlStates *p)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment