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 #include "config.h" 20 #include "wine/port.h" 21 22 #include "jscript.h" 23 #include "objsafe.h" 24 #include "mshtmhst.h" 25 26 #include "wine/debug.h" 27 28 WINE_DEFAULT_DEBUG_CHANNEL(jscript); 29 30 /* Defined as extern in urlmon.idl, but not exported by uuid.lib */ 31 const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY = 32 {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}}; 33 34 static IInternetHostSecurityManager *get_sec_mgr(script_ctx_t *ctx) 35 { 36 IInternetHostSecurityManager *secmgr; 37 IServiceProvider *sp; 38 HRESULT hres; 39 40 if(!ctx->site) 41 return NULL; 42 43 if(ctx->secmgr) 44 return ctx->secmgr; 45 46 hres = IActiveScriptSite_QueryInterface(ctx->site, &IID_IServiceProvider, (void**)&sp); 47 if(FAILED(hres)) 48 return NULL; 49 50 hres = IServiceProvider_QueryService(sp, &SID_SInternetHostSecurityManager, &IID_IInternetHostSecurityManager, 51 (void**)&secmgr); 52 IServiceProvider_Release(sp); 53 if(FAILED(hres)) 54 return NULL; 55 56 return ctx->secmgr = secmgr; 57 } 58 59 static IUnknown *create_activex_object(script_ctx_t *ctx, const WCHAR *progid) 60 { 61 IInternetHostSecurityManager *secmgr = NULL; 62 IObjectWithSite *obj_site; 63 struct CONFIRMSAFETY cs; 64 IClassFactoryEx *cfex; 65 IClassFactory *cf; 66 DWORD policy_size; 67 BYTE *bpolicy; 68 IUnknown *obj; 69 DWORD policy; 70 GUID guid; 71 HRESULT hres; 72 73 TRACE("%s\n", debugstr_w(progid)); 74 75 hres = CLSIDFromProgID(progid, &guid); 76 if(FAILED(hres)) 77 return NULL; 78 79 TRACE("GUID %s\n", debugstr_guid(&guid)); 80 81 if(ctx->safeopt & INTERFACE_USES_SECURITY_MANAGER) { 82 secmgr = get_sec_mgr(ctx); 83 if(!secmgr) 84 return NULL; 85 86 policy = 0; 87 hres = IInternetHostSecurityManager_ProcessUrlAction(secmgr, URLACTION_ACTIVEX_RUN, 88 (BYTE*)&policy, sizeof(policy), (BYTE*)&guid, sizeof(GUID), 0, 0); 89 if(FAILED(hres) || policy != URLPOLICY_ALLOW) 90 return NULL; 91 } 92 93 hres = CoGetClassObject(&guid, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, NULL, &IID_IClassFactory, (void**)&cf); 94 if(FAILED(hres)) 95 return NULL; 96 97 hres = IClassFactory_QueryInterface(cf, &IID_IClassFactoryEx, (void**)&cfex); 98 if(SUCCEEDED(hres)) { 99 FIXME("Use IClassFactoryEx\n"); 100 IClassFactoryEx_Release(cfex); 101 } 102 103 hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj); 104 if(FAILED(hres)) 105 return NULL; 106 107 if(secmgr) { 108 cs.clsid = guid; 109 cs.pUnk = obj; 110 cs.dwFlags = 0; 111 hres = IInternetHostSecurityManager_QueryCustomPolicy(secmgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY, 112 &bpolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0); 113 if(SUCCEEDED(hres)) { 114 policy = policy_size >= sizeof(DWORD) ? *(DWORD*)bpolicy : URLPOLICY_DISALLOW; 115 CoTaskMemFree(bpolicy); 116 } 117 118 if(FAILED(hres) || policy != URLPOLICY_ALLOW) { 119 IUnknown_Release(obj); 120 return NULL; 121 } 122 } 123 124 hres = IUnknown_QueryInterface(obj, &IID_IObjectWithSite, (void**)&obj_site); 125 if(SUCCEEDED(hres)) { 126 IUnknown *ax_site; 127 128 ax_site = create_ax_site(ctx); 129 if(ax_site) { 130 hres = IObjectWithSite_SetSite(obj_site, ax_site); 131 IUnknown_Release(ax_site); 132 } 133 IObjectWithSite_Release(obj_site); 134 if(!ax_site || FAILED(hres)) { 135 IUnknown_Release(obj); 136 return NULL; 137 } 138 } 139 140 return obj; 141 } 142 143 static HRESULT ActiveXObject_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, 144 jsval_t *r) 145 { 146 jsstr_t * progid_str; 147 const WCHAR *progid; 148 IDispatch *disp; 149 IUnknown *obj; 150 HRESULT hres; 151 152 TRACE("\n"); 153 154 if(flags != DISPATCH_CONSTRUCT) { 155 FIXME("unsupported flags %x\n", flags); 156 return E_NOTIMPL; 157 } 158 159 if(ctx->safeopt != (INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACE_USES_DISPEX|INTERFACE_USES_SECURITY_MANAGER) 160 && ctx->safeopt != INTERFACE_USES_DISPEX) { 161 FIXME("Unsupported safeopt %x\n", ctx->safeopt); 162 return E_NOTIMPL; 163 } 164 165 if(argc != 1) { 166 FIXME("unsupported argc %d\n", argc); 167 return E_NOTIMPL; 168 } 169 170 hres = to_flat_string(ctx, argv[0], &progid_str, &progid); 171 if(FAILED(hres)) 172 return hres; 173 174 obj = create_activex_object(ctx, progid); 175 jsstr_release(progid_str); 176 if(!obj) 177 return throw_generic_error(ctx, JS_E_CANNOT_CREATE_OBJ, NULL); 178 179 hres = IUnknown_QueryInterface(obj, &IID_IDispatch, (void**)&disp); 180 IUnknown_Release(obj); 181 if(FAILED(hres)) { 182 FIXME("Object does not support IDispatch\n"); 183 return E_NOTIMPL; 184 } 185 186 *r = jsval_disp(disp); 187 return S_OK; 188 } 189 190 HRESULT create_activex_constr(script_ctx_t *ctx, jsdisp_t **ret) 191 { 192 jsdisp_t *prototype; 193 HRESULT hres; 194 195 static const WCHAR ActiveXObjectW[] = {'A','c','t','i','v','e','X','O','b','j','e','c','t',0}; 196 197 hres = create_object(ctx, NULL, &prototype); 198 if(FAILED(hres)) 199 return hres; 200 201 hres = create_builtin_function(ctx, ActiveXObject_value, ActiveXObjectW, NULL, 202 PROPF_CONSTR|1, prototype, ret); 203 204 jsdisp_release(prototype); 205 return hres; 206 } 207