1 /* 2 * Copyright 2009 Jacek Caban for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 20 #include "jscript.h" 21 #include "objsafe.h" 22 #include "mshtmhst.h" 23 24 #include "wine/debug.h" 25 26 WINE_DEFAULT_DEBUG_CHANNEL(jscript); 27 28 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */ 29 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY = 30 {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}}; 31 32 static IInternetHostSecurityManager *get_sec_mgr(script_ctx_t *ctx) 33 { 34 IInternetHostSecurityManager *secmgr; 35 IServiceProvider *sp; 36 HRESULT hres; 37 38 if(!ctx->site) 39 return NULL; 40 41 if(ctx->secmgr) 42 return ctx->secmgr; 43 44 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp); 45 if(FAILED(hres)) 46 return NULL; 47 48 hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager, &IID_IInternetHostSecurityManager, 49 (void**)&secmgr); 50 IServiceProvider_Release(sp); 51 if(FAILED(hres)) 52 return NULL; 53 54 return ctx->secmgr = secmgr; 55 } 56 57 static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid) 58 { 59 IInternetHostSecurityManager *secmgr = NULL; 60 IObjectWithSite *obj_site; 61 struct CONFIRMSAFETY cs; 62 IClassFactoryEx *cfex; 63 IClassFactory *cf; 64 DWORD policy_size; 65 BYTE *bpolicy; 66 IUnknown *obj; 67 DWORD policy; 68 GUID guid; 69 HRESULT hres; 70 71 TRACE("%s\n", debugstr_w(progid)); 72 73 hres = CLSIDFromProgID(progid, &guid); 74 if(FAILED(hres)) 75 return NULL; 76 77 TRACE("GUID %s\n", debugstr_guid(&guid)); 78 79 if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) { 80 secmgr = get_sec_mgr(ctx); 81 if(!secmgr) 82 return NULL; 83 84 policy = 0; 85 hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, URLACTION_ACTIVEX_RUN, 86 (BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 0); 87 if(FAILED(hres) || policy != URLPOLICY_ALLOW) 88 return NULL; 89 } 90 91 hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf); 92 if(FAILED(hres)) 93 return NULL; 94 95 hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex); 96 if(SUCCEEDED(hres)) { 97 FIXME("Use IClassFactoryEx\n"); 98 IClassFactoryEx_Release(cfex); 99 } 100 101 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj); 102 if(FAILED(hres)) 103 return NULL; 104 105 if(secmgr) { 106 cs.clsid = guid; 107 cs.pUnk = obj; 108 cs.dwFlags = 0; 109 hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, 110 &bpolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); 111 if(SUCCEEDED(hres)) { 112 policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : URLPOLICY_DISALLOW; 113 CoTaskMemFree(bpolicy); 114 } 115 116 if(FAILED(hres) || policy != URLPOLICY_ALLOW) { 117 IUnknown_Release(obj); 118 return NULL; 119 } 120 } 121 122 hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site); 123 if(SUCCEEDED(hres)) { 124 IUnknown *ax_site; 125 126 ax_site = create_ax_site(ctx); 127 if(ax_site) { 128 hres = IObjectWithSite_SetSite(obj_site, ax_site); 129 IUnknown_Release(ax_site); 130 } 131 IObjectWithSite_Release(obj_site); 132 if(!ax_site || FAILED(hres)) { 133 IUnknown_Release(obj); 134 return NULL; 135 } 136 } 137 138 return obj; 139 } 140 141 static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, 142 jsval_t *r) 143 { 144 jsstr_t * progid_str; 145 const WCHAR *progid; 146 IDispatch *disp; 147 IUnknown *obj; 148 HRESULT hres; 149 150 TRACE("\n"); 151 152 if(flags != DISPATCH_CONSTRUCT) { 153 FIXME("unsupported flags %x\n", flags); 154 return E_NOTIMPL; 155 } 156 157 if(ctx->safeopt != (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER) 158 && ctx->safeopt != INTERFACE_USES_DISPEX) { 159 FIXME("Unsupported safeopt %x\n", ctx->safeopt); 160 return E_NOTIMPL; 161 } 162 163 if(argc != 1) { 164 FIXME("unsupported argc %d\n", argc); 165 return E_NOTIMPL; 166 } 167 168 hres = to_flat_string(ctx, argv[0], &progid_str, &progid); 169 if(FAILED(hres)) 170 return hres; 171 172 obj = create_activex_object(ctx, progid); 173 jsstr_release(progid_str); 174 if(!obj) 175 return throw_generic_error(ctx, JS_E_CANNOT_CREATE_OBJ, NULL); 176 177 hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&disp); 178 IUnknown_Release(obj); 179 if(FAILED(hres)) { 180 FIXME("Object does not support IDispatch\n"); 181 return E_NOTIMPL; 182 } 183 184 *r = jsval_disp(disp); 185 return S_OK; 186 } 187 188 HRESULT create_activex_constr(script_ctx_t *ctx, jsdisp_t **ret) 189 { 190 jsdisp_t *prototype; 191 HRESULT hres; 192 193 static const WCHAR ActiveXObjectW[] = {'A','c','t','i','v','e','X','O','b','j','e','c','t',0}; 194 195 hres = create_object(ctx, NULL, &prototype); 196 if(FAILED(hres)) 197 return hres; 198 199 hres = create_builtin_function(ctx, ActiveXObject_value, ActiveXObjectW, NULL, 200 PROPF_CONSTR|1, prototype, ret); 201 202 jsdisp_release(prototype); 203 return hres; 204 } 205