Jacek Caban : vbscript: Added support for IObjectWithSite in create_object.

Alexandre Julliard julliard at winehq.org
Thu Sep 22 13:39:48 CDT 2011


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Sep 22 14:25:50 2011 +0200

vbscript: Added support for IObjectWithSite in create_object.

---

 dlls/vbscript/global.c   |   14 +++++-
 dlls/vbscript/vbscript.c |   98 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/vbscript/vbscript.h |    2 +
 3 files changed, 111 insertions(+), 3 deletions(-)

diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c
index 5af7e16..771236d 100644
--- a/dlls/vbscript/global.c
+++ b/dlls/vbscript/global.c
@@ -122,10 +122,18 @@ static IUnknown *create_object(script_ctx_t *ctx, const WCHAR *progid)
 
     hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site);
     if(SUCCEEDED(hres)) {
-        FIXME("ObjectWithSite\n");
+        IUnknown *ax_site;
+
+        ax_site = create_ax_site(ctx);
+        if(ax_site) {
+            hres = IObjectWithSite_SetSite(obj_site, ax_site);
+            IUnknown_Release(ax_site);
+        }
         IObjectWithSite_Release(obj_site);
-        IUnknown_Release(obj);
-        return NULL;
+        if(!ax_site || FAILED(hres)) {
+            IUnknown_Release(obj);
+            return NULL;
+        }
     }
 
     return obj;
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index d4e8cca..7bea9f2b 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -664,3 +664,101 @@ HRESULT WINAPI VBScriptFactory_CreateInstance(IClassFactory *iface, IUnknown *pU
     IActiveScript_Release(&ret->IActiveScript_iface);
     return hres;
 }
+
+typedef struct {
+    IServiceProvider IServiceProvider_iface;
+
+    LONG ref;
+
+    IServiceProvider *sp;
+} AXSite;
+
+static inline AXSite *impl_from_IServiceProvider(IServiceProvider *iface)
+{
+    return CONTAINING_RECORD(iface, AXSite, IServiceProvider_iface);
+}
+
+static HRESULT WINAPI AXSite_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
+{
+    AXSite *This = impl_from_IServiceProvider(iface);
+
+    if(IsEqualGUID(&IID_IUnknown, riid)) {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = &This->IServiceProvider_iface;
+    }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
+        TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
+        *ppv = &This->IServiceProvider_iface;
+    }else {
+        TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI AXSite_AddRef(IServiceProvider *iface)
+{
+    AXSite *This = impl_from_IServiceProvider(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI AXSite_Release(IServiceProvider *iface)
+{
+    AXSite *This = impl_from_IServiceProvider(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref)
+        heap_free(This);
+
+    return ref;
+}
+
+static HRESULT WINAPI AXSite_QueryService(IServiceProvider *iface,
+        REFGUID guidService, REFIID riid, void **ppv)
+{
+    AXSite *This = impl_from_IServiceProvider(iface);
+
+    TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
+
+    return IServiceProvider_QueryService(This->sp, guidService, riid, ppv);
+}
+
+static IServiceProviderVtbl AXSiteVtbl = {
+    AXSite_QueryInterface,
+    AXSite_AddRef,
+    AXSite_Release,
+    AXSite_QueryService
+};
+
+IUnknown *create_ax_site(script_ctx_t *ctx)
+{
+    IServiceProvider *sp;
+    AXSite *ret;
+    HRESULT hres;
+
+    hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp);
+    if(FAILED(hres)) {
+        ERR("Could not get IServiceProvider iface: %08x\n", hres);
+        return NULL;
+    }
+
+    ret = heap_alloc(sizeof(*ret));
+    if(!ret) {
+        IServiceProvider_Release(sp);
+        return NULL;
+    }
+
+    ret->IServiceProvider_iface.lpVtbl = &AXSiteVtbl;
+    ret->ref = 1;
+    ret->sp = sp;
+
+    return (IUnknown*)&ret->IServiceProvider_iface;
+}
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index d8134fa..491003b 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -171,6 +171,8 @@ struct _script_ctx_t {
 HRESULT init_global(script_ctx_t*);
 HRESULT init_err(script_ctx_t*);
 
+IUnknown *create_ax_site(script_ctx_t*) DECLSPEC_HIDDEN;
+
 typedef enum {
     ARG_NONE = 0,
     ARG_STR,




More information about the wine-cvs mailing list