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

Alexandre Julliard julliard at winehq.org
Tue Jun 23 15:52:53 CDT 2020


Module: wine
Branch: master
Commit: fcf6d67b83c31983eae68ebbf359cf738d38e283
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=fcf6d67b83c31983eae68ebbf359cf738d38e283

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Jun 23 16:41:04 2020 +0200

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

Based on patch by Gabriel Ivăncescu.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msscript.ocx/msscript.c | 93 ++++++++++++++++++++++++++------------------
 1 file changed, 55 insertions(+), 38 deletions(-)

diff --git a/dlls/msscript.ocx/msscript.c b/dlls/msscript.ocx/msscript.c
index f7917b2327..8b36f3af9a 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;
@@ -83,9 +86,8 @@ typedef struct ScriptHost {
     CLSID clsid;
 
     unsigned int module_count;
-
     struct list named_items;
-} ScriptHost;
+};
 
 struct ScriptControl {
     IScriptControl IScriptControl_iface;
@@ -355,25 +357,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);
@@ -572,6 +555,26 @@ static const IServiceProviderVtbl ServiceProviderVtbl = {
     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)
 {
     ScriptModule *This = impl_from_IScriptModule(iface);
@@ -610,7 +613,11 @@ static ULONG WINAPI ScriptModule_Release(IScriptModule *iface)
     TRACE("(%p) ref=%d\n", This, ref);
 
     if (!ref)
+    {
+        detach_script_host(This->host);
+        IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
         heap_free(This);
+    }
 
     return ref;
 }
@@ -756,7 +763,7 @@ static const IScriptModuleVtbl ScriptModuleVtbl = {
     ScriptModule_Run
 };
 
-static ScriptModule *create_module(void)
+static ScriptModule *create_module(ScriptHost *host)
 {
     ScriptModule *module;
 
@@ -764,6 +771,8 @@ static ScriptModule *create_module(void)
 
     module->IScriptModule_iface.lpVtbl = &ScriptModuleVtbl;
     module->ref = 1;
+    module->host = host;
+    IActiveScriptSite_AddRef(&host->IActiveScriptSite_iface);
     return module;
 }
 
@@ -992,7 +1001,7 @@ static HRESULT init_script_host(const CLSID *clsid, ScriptHost **ret)
     return S_OK;
 
 failed:
-    release_script_engine(host);
+    detach_script_host(host);
     return hr;
 }
 
@@ -1072,7 +1081,7 @@ static ULONG WINAPI ScriptControl_Release(IScriptControl *iface)
         if (This->host)
         {
             release_modules(This);
-            release_script_engine(This->host);
+            IActiveScriptSite_Release(&This->host->IActiveScriptSite_iface);
         }
         heap_free(This);
     }
@@ -1164,6 +1173,7 @@ static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR lan
 {
     ScriptControl *This = impl_from_IScriptControl(iface);
     CLSID clsid;
+    HRESULT hres;
 
     TRACE("(%p)->(%s)\n", This, debugstr_w(language));
 
@@ -1171,25 +1181,32 @@ static HRESULT WINAPI ScriptControl_put_Language(IScriptControl *iface, BSTR lan
         return CTL_E_INVALIDPROPERTYVALUE;
 
     if (This->host) {
-        release_script_engine(This->host);
+        release_modules(This);
         This->host = NULL;
     }
 
-    /* Alloc global module */
-    This->modules = heap_alloc_zero(sizeof(*This->modules));
-    if (!This->modules) return E_OUTOFMEMORY;
-
-    This->modules[0] = create_module();
-    if (!This->modules[0]) {
-        heap_free(This->modules);
-        This->modules = NULL;
-        return E_OUTOFMEMORY;
-    }
-
     if (!language)
         return S_OK;
 
-    return init_script_host(&clsid, &This->host);
+    hres = init_script_host(&clsid, &This->host);
+    if (FAILED(hres))
+        return hres;
+
+    /* Alloc global module */
+    This->modules = heap_alloc_zero(sizeof(*This->modules));
+    if (This->modules) {
+        This->modules[0] = create_module(This->host);
+        if (!This->modules[0]) {
+            heap_free(This->modules);
+            This->modules = NULL;
+            hres = E_OUTOFMEMORY;
+        }
+    }
+    if (FAILED(hres)) {
+        This->host = NULL;
+        detach_script_host(This->host);
+    }
+    return hres;
 }
 
 static HRESULT WINAPI ScriptControl_get_State(IScriptControl *iface, ScriptControlStates *p)




More information about the wine-cvs mailing list