Jacek Caban : scrobj: Add stub IActiveScriptSite implementation.

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


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

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

scrobj: Add stub IActiveScriptSite implementation.

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

---

 dlls/scrobj/scrobj.c | 221 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 217 insertions(+), 4 deletions(-)

diff --git a/dlls/scrobj/scrobj.c b/dlls/scrobj/scrobj.c
index e1dc6182f3..8fc95827a7 100644
--- a/dlls/scrobj/scrobj.c
+++ b/dlls/scrobj/scrobj.c
@@ -25,6 +25,7 @@
 #include "ole2.h"
 #include "olectl.h"
 #include "rpcproxy.h"
+#include "activscp.h"
 
 #include "initguid.h"
 #include "scrobj.h"
@@ -76,10 +77,19 @@ struct scriptlet_factory
     WCHAR *classid_str;
     CLSID classid;
 
+    struct list hosts;
     struct list members;
     struct list scripts;
 };
 
+struct script_host
+{
+    IActiveScriptSite IActiveScriptSite_iface;
+    LONG ref;
+    struct list entry;
+    WCHAR *language;
+};
+
 typedef enum tid_t
 {
     NULL_tid,
@@ -155,6 +165,202 @@ static void release_typelib(void)
     ITypeLib_Release(typelib);
 }
 
+static WCHAR *heap_strdupW(const WCHAR *str)
+{
+    WCHAR *ret;
+    size_t size = (wcslen(str) + 1) * sizeof(WCHAR);
+    if (!(ret = heap_alloc(size))) return NULL;
+    memcpy(ret, str, size);
+    return ret;
+}
+
+static inline struct script_host *impl_from_IActiveScriptSite(IActiveScriptSite *iface)
+{
+    return CONTAINING_RECORD(iface, struct script_host, IActiveScriptSite_iface);
+}
+
+static HRESULT WINAPI ActiveScriptSite_QueryInterface(IActiveScriptSite *iface, REFIID riid, void **ppv)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+
+    if (IsEqualGUID(&IID_IUnknown, riid))
+    {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = &This->IActiveScriptSite_iface;
+    }
+    else if (IsEqualGUID(&IID_IActiveScriptSite, riid))
+    {
+        TRACE("(%p)->(IID_IActiveScriptSite %p)\n", This, ppv);
+        *ppv = &This->IActiveScriptSite_iface;
+    }
+    else
+    {
+        FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI ActiveScriptSite_AddRef(IActiveScriptSite *iface)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI ActiveScriptSite_Release(IActiveScriptSite *iface)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref) {
+        heap_free(This->language);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetLCID(IActiveScriptSite *iface, LCID *lcid)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+
+    TRACE("(%p, %p)\n", This, lcid);
+
+    *lcid = GetUserDefaultLCID();
+    return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPCOLESTR name, DWORD mask,
+    IUnknown **unk, ITypeInfo **ti)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+    FIXME("(%p, %s, %#x, %p, %p)\n", This, debugstr_w(name), mask, unk, ti);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_GetDocVersionString(IActiveScriptSite *iface, BSTR *version)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+    FIXME("(%p, %p)\n", This, version);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptTerminate(IActiveScriptSite *iface, const VARIANT *result,
+    const EXCEPINFO *ei)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+    FIXME("(%p, %s, %p)\n", This, debugstr_variant(result), ei);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, SCRIPTSTATE state)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+    TRACE("(%p, %d)\n", This, state);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *script_error)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+    FIXME("(%p, %p)\n", This, script_error);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnEnterScript(IActiveScriptSite *iface)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+    TRACE("(%p)\n", This);
+    return S_OK;
+}
+
+static HRESULT WINAPI ActiveScriptSite_OnLeaveScript(IActiveScriptSite *iface)
+{
+    struct script_host *This = impl_from_IActiveScriptSite(iface);
+    TRACE("(%p)\n", This);
+    return S_OK;
+}
+
+static const IActiveScriptSiteVtbl ActiveScriptSiteVtbl = {
+    ActiveScriptSite_QueryInterface,
+    ActiveScriptSite_AddRef,
+    ActiveScriptSite_Release,
+    ActiveScriptSite_GetLCID,
+    ActiveScriptSite_GetItemInfo,
+    ActiveScriptSite_GetDocVersionString,
+    ActiveScriptSite_OnScriptTerminate,
+    ActiveScriptSite_OnStateChange,
+    ActiveScriptSite_OnScriptError,
+    ActiveScriptSite_OnEnterScript,
+    ActiveScriptSite_OnLeaveScript
+};
+
+static struct script_host *find_script_host(struct list *hosts, const WCHAR *language)
+{
+    struct script_host *host;
+    LIST_FOR_EACH_ENTRY(host, hosts, struct script_host, entry)
+    {
+        if (!wcscmp(host->language, language)) return host;
+    }
+    return NULL;
+}
+
+static HRESULT create_script_host(const WCHAR *language, struct list *hosts)
+{
+    struct script_host *host;
+
+    if (!(host = heap_alloc_zero(sizeof(*host)))) return E_OUTOFMEMORY;
+
+    host->IActiveScriptSite_iface.lpVtbl = &ActiveScriptSiteVtbl;
+    host->ref = 1;
+
+    if (!(host->language = heap_strdupW(language)))
+    {
+        IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
+        return E_OUTOFMEMORY;
+    }
+
+    list_add_tail(hosts, &host->entry);
+    return S_OK;
+}
+
+static void detach_script_hosts(struct list *hosts)
+{
+    while (!list_empty(hosts))
+    {
+        struct script_host *host = LIST_ENTRY(list_head(hosts), struct script_host, entry);
+        list_remove(&host->entry);
+        IActiveScriptSite_Release(&host->IActiveScriptSite_iface);
+    }
+}
+
+static HRESULT create_scriptlet_hosts(struct scriptlet_factory *factory, struct list *hosts)
+{
+    struct scriptlet_script *script;
+    HRESULT hres;
+
+    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);
+        if (FAILED(hres))
+        {
+            detach_script_hosts(hosts);
+            return hres;
+        }
+    }
+    return S_OK;
+}
+
 static const char *debugstr_xml_name(struct scriptlet_factory *factory)
 {
     const WCHAR *str;
@@ -596,6 +802,7 @@ static ULONG WINAPI scriptlet_factory_Release(IClassFactory *iface)
     {
         if (This->moniker) IMoniker_Release(This->moniker);
         if (This->xml_reader) IXmlReader_Release(This->xml_reader);
+        detach_script_hosts(&This->hosts);
         while (!list_empty(&This->members))
         {
             struct scriptlet_member *member = LIST_ENTRY(list_head(&This->members), struct scriptlet_member, entry);
@@ -666,6 +873,7 @@ static HRESULT create_scriptlet_factory(const WCHAR *url, struct scriptlet_facto
 
     factory->IClassFactory_iface.lpVtbl = &scriptlet_factory_vtbl;
     factory->ref = 1;
+    list_init(&factory->hosts);
     list_init(&factory->members);
     list_init(&factory->scripts);
 
@@ -1182,16 +1390,21 @@ HRESULT WINAPI DllInstall(BOOL install, const WCHAR *arg)
     {
         if (factory->have_registration)
         {
-            if (install)
-                hres = register_scriptlet(factory);
-            else
-                hres = unregister_scriptlet(factory);
+            /* validate scripts */
+            hres = create_scriptlet_hosts(factory, &factory->hosts);
         }
         else
         {
             FIXME("No registration info\n");
             hres = E_FAIL;
         }
+        if (SUCCEEDED(hres))
+        {
+            if (install)
+                hres = register_scriptlet(factory);
+            else
+                hres = unregister_scriptlet(factory);
+        }
         IClassFactory_Release(&factory->IClassFactory_iface);
     }
 




More information about the wine-cvs mailing list