Jacek Caban : scrobj: Create script engine instances for script hosts.

Alexandre Julliard julliard at winehq.org
Fri Sep 20 15:54:43 CDT 2019


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Sep 20 16:24:04 2019 +0200

scrobj: Create script engine instances for script hosts.

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

---

 dlls/scrobj/scrobj.c       | 108 +++++++++++++++++++++++++++++++++++++++++++--
 dlls/scrobj/tests/scrobj.c |   5 ---
 2 files changed, 105 insertions(+), 8 deletions(-)

diff --git a/dlls/scrobj/scrobj.c b/dlls/scrobj/scrobj.c
index 4424359d15..710cdfa738 100644
--- a/dlls/scrobj/scrobj.c
+++ b/dlls/scrobj/scrobj.c
@@ -26,6 +26,7 @@
 #include "olectl.h"
 #include "rpcproxy.h"
 #include "activscp.h"
+#include "mshtmhst.h"
 
 #include "initguid.h"
 #include "scrobj.h"
@@ -37,6 +38,20 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(scrobj);
 
+#ifdef _WIN64
+
+#define IActiveScriptParse_Release IActiveScriptParse64_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
+
+#else
+
+#define IActiveScriptParse_Release IActiveScriptParse32_Release
+#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
+#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
+
+#endif
+
 static HINSTANCE scrobj_instance;
 
 struct scriptlet_member
@@ -87,9 +102,15 @@ struct script_host
     IActiveScriptSite IActiveScriptSite_iface;
     IActiveScriptSiteWindow IActiveScriptSiteWindow_iface;
     IServiceProvider IServiceProvider_iface;
+
     LONG ref;
     struct list entry;
+
     WCHAR *language;
+
+    IActiveScript *active_script;
+    IActiveScriptParse *parser;
+    BOOL cloned;
 };
 
 typedef enum tid_t
@@ -409,9 +430,71 @@ static struct script_host *find_script_host(struct list *hosts, const WCHAR *lan
     return NULL;
 }
 
-static HRESULT create_script_host(const WCHAR *language, struct list *hosts)
+static HRESULT init_script_host(struct script_host *host, IActiveScript *clone)
+{
+    HRESULT hres;
+
+    if (!clone)
+    {
+        IClassFactoryEx *factory_ex;
+        IClassFactory *factory;
+        IUnknown *unk;
+        CLSID clsid;
+
+        if (FAILED(hres = CLSIDFromProgID(host->language, &clsid)))
+        {
+            WARN("Could not find script engine for %s\n", debugstr_w(host->language));
+            return hres;
+        }
+
+        hres = CoGetClassObject(&clsid, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, NULL,
+                                &IID_IClassFactory, (void**)&factory);
+        if (FAILED(hres)) return hres;
+
+        hres = IClassFactory_QueryInterface(factory, &IID_IClassFactoryEx, (void**)&factory_ex);
+        if (SUCCEEDED(hres))
+        {
+            FIXME("Use IClassFactoryEx\n");
+            IClassFactoryEx_Release(factory_ex);
+        }
+
+        hres = IClassFactory_CreateInstance(factory, NULL, &IID_IUnknown, (void**)&unk);
+        IClassFactory_Release(factory);
+        if (FAILED(hres)) return hres;
+
+        hres = IUnknown_QueryInterface(unk, &IID_IActiveScript, (void**)&host->active_script);
+        IUnknown_Release(unk);
+        if (FAILED(hres)) return hres;
+    }
+    else
+    {
+        IActiveScript_AddRef(clone);
+        host->active_script = clone;
+        host->cloned = TRUE;
+    }
+
+    hres = IActiveScript_QueryInterface(host->active_script, &IID_IActiveScriptParse, (void**)&host->parser);
+    if (FAILED(hres)) return hres;
+
+    if (!clone)
+    {
+        hres = IActiveScriptParse_InitNew(host->parser);
+        if (FAILED(hres))
+        {
+            IActiveScriptParse_Release(host->parser);
+            host->parser = NULL;
+            return hres;
+        }
+    }
+
+    return IActiveScript_SetScriptSite(host->active_script, &host->IActiveScriptSite_iface);
+}
+
+static HRESULT create_script_host(const WCHAR *language, IActiveScript *origin_script, struct list *hosts)
 {
+    IActiveScript *clone = NULL;
     struct script_host *host;
+    HRESULT hres;
 
     if (!(host = heap_alloc_zero(sizeof(*host)))) return E_OUTOFMEMORY;
 
@@ -426,8 +509,16 @@ static HRESULT create_script_host(const WCHAR *language, struct list *hosts)
         return E_OUTOFMEMORY;
     }
 
+    if (origin_script)
+    {
+        hres = IActiveScript_Clone(origin_script, &clone);
+        if (FAILED(hres)) clone = NULL;
+    }
+
     list_add_tail(hosts, &host->entry);
-    return S_OK;
+    hres = init_script_host(host, clone);
+    if (clone) IActiveScript_Release(clone);
+    return hres;
 }
 
 static void detach_script_hosts(struct list *hosts)
@@ -436,6 +527,17 @@ static void detach_script_hosts(struct list *hosts)
     {
         struct script_host *host = LIST_ENTRY(list_head(hosts), struct script_host, entry);
         list_remove(&host->entry);
+        if (host->parser)
+        {
+            IActiveScript_Close(host->active_script);
+            IActiveScriptParse_Release(host->parser);
+            host->parser = NULL;
+        }
+        if (host->active_script)
+        {
+            IActiveScript_Release(host->active_script);
+            host->active_script = NULL;
+        }
         IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
     }
 }
@@ -448,7 +550,7 @@ static HRESULT create_scriptlet_hosts(struct scriptlet_factory *factory, struct
     LIST_FOR_EACH_ENTRY(script, &factory->scripts, struct scriptlet_script, entry)
     {
         if (find_script_host(hosts, script->language)) continue;
-        hres = create_script_host(script->language, hosts);
+        hres = create_script_host(script->language, NULL, hosts);
         if (FAILED(hres))
         {
             detach_script_hosts(hosts);
diff --git a/dlls/scrobj/tests/scrobj.c b/dlls/scrobj/tests/scrobj.c
index 259417e60e..d3e5631d05 100644
--- a/dlls/scrobj/tests/scrobj.c
+++ b/dlls/scrobj/tests/scrobj.c
@@ -716,19 +716,14 @@ static void register_script_object(BOOL do_register, const WCHAR *file_name)
     SET_EXPECT(SetScriptState_UNINITIALIZED);
     SET_EXPECT(Close);
     hres = pDllInstall(do_register, file_name);
-    todo_wine
     CHECK_CALLED(CreateInstance);
-    todo_wine
     CHECK_CALLED(QI_IActiveScriptParse);
-    todo_wine
     CHECK_CALLED(InitNew);
-    todo_wine
     CHECK_CALLED(SetScriptSite);
     todo_wine
     CHECK_CALLED(ParseScriptText);
     todo_wine
     CHECK_CALLED(SetScriptState_UNINITIALIZED);
-    todo_wine
     CHECK_CALLED(Close);
     ok(hres == S_OK, "DllInstall failed: %08x\n", hres);
     if (FAILED(hres))




More information about the wine-cvs mailing list