diff --git a/dlls/vbscript/Makefile.in b/dlls/vbscript/Makefile.in index 2da0c33a6e5..e4765a0d518 100644 --- a/dlls/vbscript/Makefile.in +++ b/dlls/vbscript/Makefile.in @@ -1,5 +1,5 @@ MODULE = vbscript.dll -IMPORTS = oleaut32 +IMPORTS = oleaut32 ole32 C_SRCS = \ compile.c \ diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c index 3d58ea7f9cc..5af7e16e905 100644 --- a/dlls/vbscript/global.c +++ b/dlls/vbscript/global.c @@ -19,10 +19,118 @@ #include "vbscript.h" #include "vbscript_defs.h" +#include "mshtmhst.h" +#include "objsafe.h" + #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(vbscript); +#define VB_E_CANNOT_CREATE_OBJ 0x800a01ad + +/* Defined as extern in urlmon.idl, but not exported by uuid.lib */ +const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY = + {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}}; + +static IInternetHostSecurityManager *get_sec_mgr(script_ctx_t *ctx) +{ + IInternetHostSecurityManager *secmgr; + IServiceProvider *sp; + HRESULT hres; + + if(!ctx->site) + return NULL; + + if(ctx->secmgr) + return ctx->secmgr; + + hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp); + if(FAILED(hres)) + return NULL; + + hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager, &IID_IInternetHostSecurityManager, + (void**)&secmgr); + IServiceProvider_Release(sp); + if(FAILED(hres)) + return NULL; + + return ctx->secmgr = secmgr; +} + +static IUnknown *create_object(script_ctx_t *ctx, const WCHAR *progid) +{ + IInternetHostSecurityManager *secmgr = NULL; + IObjectWithSite *obj_site; + struct CONFIRMSAFETY cs; + IClassFactoryEx *cfex; + IClassFactory *cf; + DWORD policy_size; + BYTE *bpolicy; + IUnknown *obj; + DWORD policy; + GUID guid; + HRESULT hres; + + hres = CLSIDFromProgID(progid, &guid); + if(FAILED(hres)) + return NULL; + + TRACE("GUID %s\n", debugstr_guid(&guid)); + + if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) { + secmgr = get_sec_mgr(ctx); + if(!secmgr) + return NULL; + + policy = 0; + hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, URLACTION_ACTIVEX_RUN, + (BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 0); + if(FAILED(hres) || policy != URLPOLICY_ALLOW) + return NULL; + } + + hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf); + if(FAILED(hres)) + return NULL; + + hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex); + if(SUCCEEDED(hres)) { + FIXME("Use IClassFactoryEx\n"); + IClassFactoryEx_Release(cfex); + } + + hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj); + if(FAILED(hres)) + return NULL; + + if(secmgr) { + cs.clsid = guid; + cs.pUnk = obj; + cs.dwFlags = 0; + hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, + &bpolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); + if(SUCCEEDED(hres)) { + policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : URLPOLICY_DISALLOW; + CoTaskMemFree(bpolicy); + } + + if(FAILED(hres) || policy != URLPOLICY_ALLOW) { + IUnknown_Release(obj); + return NULL; + } + } + + hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site); + if(SUCCEEDED(hres)) { + FIXME("ObjectWithSite\n"); + IObjectWithSite_Release(obj_site); + IUnknown_Release(obj); + return NULL; + } + + return obj; +} + static HRESULT Global_CCur(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) { FIXME("\n"); @@ -483,8 +591,30 @@ static HRESULT Global_MsgBox(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VA static HRESULT Global_CreateObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) { - FIXME("\n"); - return E_NOTIMPL; + IUnknown *obj; + HRESULT hres; + + TRACE("(%s)\n", debugstr_variant(arg)); + + if(V_VT(arg) != VT_BSTR) { + FIXME("non-bstr arg\n"); + return E_INVALIDARG; + } + + obj = create_object(This->desc->ctx, V_BSTR(arg)); + if(!obj) + return VB_E_CANNOT_CREATE_OBJ; + + if(res) { + hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&V_DISPATCH(res)); + if(FAILED(hres)) + return hres; + + V_VT(res) = VT_DISPATCH; + } + + IUnknown_Release(obj); + return S_OK; } static HRESULT Global_GetObject(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c index 3ac95607b39..d4e8ccaafce 100644 --- a/dlls/vbscript/vbscript.c +++ b/dlls/vbscript/vbscript.c @@ -129,6 +129,8 @@ static void destroy_script(script_ctx_t *ctx) if(ctx->host_global) IDispatch_Release(ctx->host_global); + if(ctx->secmgr) + IInternetHostSecurityManager_Release(ctx->secmgr); if(ctx->site) IActiveScriptSite_Release(ctx->site); if(ctx->err_obj) @@ -516,6 +518,7 @@ static HRESULT WINAPI VBScriptParse_InitNew(IActiveScriptParse *iface) if(!ctx) return E_OUTOFMEMORY; + ctx->safeopt = This->safeopt; vbsheap_init(&ctx->heap); list_init(&ctx->objects); list_init(&ctx->code_list); diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index 4b0a569f56c..d8134fa8b55 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -143,6 +143,9 @@ struct _script_ctx_t { IActiveScriptSite *site; LCID lcid; + IInternetHostSecurityManager *secmgr; + DWORD safeopt; + IDispatch *host_global; class_desc_t script_desc; diff --git a/dlls/vbscript/vbscript_main.c b/dlls/vbscript/vbscript_main.c index 4054d35e7a5..c47227f80cb 100644 --- a/dlls/vbscript/vbscript_main.c +++ b/dlls/vbscript/vbscript_main.c @@ -20,6 +20,7 @@ #include "vbscript.h" #include "objsafe.h" +#include "mshtmhst.h" #include "rpcproxy.h" #include "vbscript_classes.h" #include "vbsglobal.h"