From d339a0b4431e1d2df8192df5e6e985001224aaf6 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 22 Sep 2011 14:25:50 +0200 Subject: [PATCH] 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 5af7e16e905..771236da4f6 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 d4e8ccaafce..7bea9f2b2fe 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 d8134fa8b55..491003bae62 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,