Signed-off-by: Gabriel Ivăncescu gabrielopcode@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; }