vbscript: Added support for IObjectWithSite in create_object.
authorJacek Caban <jacek@codeweavers.com>
Thu, 22 Sep 2011 12:25:50 +0000 (14:25 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Thu, 22 Sep 2011 15:24:42 +0000 (17:24 +0200)
dlls/vbscript/global.c
dlls/vbscript/vbscript.c
dlls/vbscript/vbscript.h

index 5af7e16e9051de695e81d191d34b462329fce13c..771236da4f6e30b6ae9b0bc2eb94d54391263404 100644 (file)
@@ -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;
index d4e8ccaafceb4b5ed4a7443f6e8860ffc6bd782a..7bea9f2b2feef99beb9c9543e32444acc7ecb412 100644 (file)
@@ -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;
+}
index d8134fa8b55c499517e9cce7a70d17b29a918115..491003bae62afd34440b0050ce10a479cb4ac938 100644 (file)
@@ -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,