Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com> --- dlls/msscript.ocx/msscript.c | 88 +++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c index 7385ce1..3d65067 100644 --- a/dlls/msscript.ocx/msscript.c +++ b/dlls/msscript.ocx/msscript.c @@ -51,6 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msscript); struct ScriptControl; typedef struct ConnectionPoint ConnectionPoint; +typedef struct ScriptHost ScriptHost; struct ConnectionPoint { IConnectionPoint IConnectionPoint_iface; @@ -68,9 +69,11 @@ struct named_item { typedef struct { IScriptModule IScriptModule_iface; LONG ref; + + ScriptHost *host; } ScriptModule; -typedef struct ScriptHost { +struct ScriptHost { IActiveScriptSite IActiveScriptSite_iface; IActiveScriptSiteWindow IActiveScriptSiteWindow_iface; IServiceProvider IServiceProvider_iface; @@ -86,7 +89,7 @@ typedef struct ScriptHost { ScriptModule **modules; struct list named_items; -} ScriptHost; +}; struct ScriptControl { IScriptControl IScriptControl_iface; @@ -353,25 +356,6 @@ static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface) 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) { ScriptHost *This = impl_from_IActiveScriptSite(iface); @@ -570,6 +554,32 @@ static const IServiceProviderVtbl ServiceProviderVtbl = { ServiceProvider_QueryService }; +static void detach_module(ScriptModule *module) +{ + ScriptHost *host = module->host; + + module->host = NULL; + + 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; + + IActiveScriptSite_Release(&host->IActiveScriptSite_iface); +} + static HRESULT WINAPI ScriptModule_QueryInterface(IScriptModule *iface, REFIID riid, void **ppv) { ScriptModule *This = impl_from_IScriptModule(iface); @@ -608,7 +618,11 @@ static ULONG WINAPI ScriptModule_Release(IScriptModule *iface) TRACE("(%p) ref=%d\n", This, ref); if (!ref) + { + if (This->host) + detach_module(This); heap_free(This); + } return ref; } @@ -754,7 +768,7 @@ static const IScriptModuleVtbl ScriptModuleVtbl = { ScriptModule_Run }; -static ScriptModule *create_module(void) +static ScriptModule *create_module(ScriptHost *host) { ScriptModule *module; @@ -762,18 +776,23 @@ static ScriptModule *create_module(void) module->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl; module->ref = 1; + module->host = host; return module; } -static void release_modules(ScriptHost *host) +static void release_modules(ScriptHost *host, BOOL force_detach) { - unsigned int i; + /* Releasing the modules might destroy the host, so keep copies */ + unsigned int i, module_count = host->module_count; + ScriptModule **modules = host->modules; - for (i = 0; i < host->module_count; i++) - IScriptModule_Release(&host->modules[i]->IScriptModule_iface); + for (i = 0; i < module_count; i++) + { + if (force_detach) detach_module(modules[i]); + IScriptModule_Release(&modules[i]->IScriptModule_iface); + } - host->module_count = 0; - heap_free(host->modules); + heap_free(modules); } static HRESULT WINAPI ScriptModuleCollection_QueryInterface(IScriptModuleCollection *iface, REFIID riid, void **ppv) @@ -951,7 +970,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret) host->modules = heap_alloc_zero(sizeof(*host->modules)); if (!host->modules) return E_OUTOFMEMORY; - host->modules[0] = create_module(); + host->modules[0] = create_module(host); if (!host->modules[0]) { heap_free(host->modules); heap_free(host); @@ -1002,8 +1021,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret) return S_OK; failed: - release_modules(host); - release_script_engine(host); + release_modules(host, FALSE); return hr; } @@ -1081,10 +1099,7 @@ static ULONG WINAPI ScriptControl_Release(IScriptControl *iface) if (This->site) IOleClientSite_Release(This->site); if (This->host) - { - release_modules(This->host); - release_script_engine(This->host); - } + release_modules(This->host, FALSE); heap_free(This); } @@ -1182,8 +1197,7 @@ static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR lan return CTL_E_INVALIDPROPERTYVALUE; if (This->host) { - release_modules(This->host); - release_script_engine(This->host); + release_modules(This->host, TRUE); This->host = NULL; } -- 2.21.0